예제 #1
0
        internal static TriggeredJobHistoryData DeserializeTriggeredJobHistoryData(JsonElement element)
        {
            Optional <string>  kind = default;
            ResourceIdentifier id   = default;
            string             name = default;
            ResourceType       type = default;
            Optional <IList <TriggeredJobRun> > runs = default;

            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("kind"))
                {
                    kind = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("id"))
                {
                    id = new ResourceIdentifier(property.Value.GetString());
                    continue;
                }
                if (property.NameEquals("name"))
                {
                    name = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("type"))
                {
                    type = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("properties"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    foreach (var property0 in property.Value.EnumerateObject())
                    {
                        if (property0.NameEquals("runs"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            List <TriggeredJobRun> array = new List <TriggeredJobRun>();
                            foreach (var item in property0.Value.EnumerateArray())
                            {
                                array.Add(TriggeredJobRun.DeserializeTriggeredJobRun(item));
                            }
                            runs = array;
                            continue;
                        }
                    }
                    continue;
                }
            }
            return(new TriggeredJobHistoryData(id, name, type, kind.Value, Optional.ToList(runs)));
        }
예제 #2
0
 private static string CalculateETag(TriggeredJobRun triggeredJobRun)
 {
     // during a job's life time, the status and endtime could change, so
     // a job run state is made of its id, status, and end time.
     return(string.Format(CultureInfo.CurrentCulture, "\"{0:x}-{1:x}-{2:x}\"",
                          triggeredJobRun.Id.GetHashCode(),
                          triggeredJobRun.Status.GetHashCode(),
                          triggeredJobRun.EndTime.Ticks.GetHashCode()));
 }
예제 #3
0
        public void DnxWebJobRunsCorrectly()
        {
            RunScenario("DnxWebJobRunsCorrectly", appManager =>
            {
                const string jobName = "dnxJob";
                var program          = @"using System;
namespace WebJob
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(""Hello Dnx!!"");
        }
    }
}";
                var project          = @"{
    ""dependencies"": {
    },
    ""frameworks"": {
        ""dnx451"": { }
    }
}";

                appManager.VfsManager.WriteAllText(TriggeredJobBinPath + "/" + jobName + "/" + "Program.cs", program);
                appManager.VfsManager.WriteAllText(TriggeredJobBinPath + "/" + jobName + "/" + "project.json", project);

                var expectedWebJob = new TriggeredJob
                {
                    Name       = jobName,
                    JobType    = "triggered",
                    RunCommand = "project.json"
                };

                var webjob = appManager.JobsManager.GetTriggeredJobAsync(jobName).Result;
                AssertTriggeredJob(expectedWebJob, webjob);
                appManager.JobsManager.InvokeTriggeredJobAsync(jobName).Wait();

                TriggeredJobRun jobRun = null;

                WaitUntilAssertVerified(
                    "Dnx Triggered job",
                    TimeSpan.FromSeconds(30),
                    () =>
                {
                    var jobHistory = appManager.JobsManager.GetTriggeredJobHistoryAsync(jobName).Result;
                    jobRun         = jobHistory.TriggeredJobRuns.First();
                    Assert.Equal("Success", jobRun.Status);
                });

                var logPath   = jobRun.OutputUrl.AbsoluteUri.Split(new[] { "/vfs/" }, StringSplitOptions.RemoveEmptyEntries).Last();
                var jobOutput = appManager.VfsManager.ReadAllText(logPath);
                Assert.True(jobOutput.Contains("Hello Dnx!!"));
            });
        }
예제 #4
0
        private async void ReportTriggeredJobFinished(string jobName, string jobRunId)
        {
            TriggeredJobRun triggeredJobRun = GetJobRun(jobName, jobRunId);

            if (triggeredJobRun == null)
            {
                return;
            }

            await _hooksManager.PublishEventAsync(HookEventTypes.TriggeredJobFinished, triggeredJobRun);
        }
예제 #5
0
        public HttpResponseMessage GetTriggeredJobRun(string jobName, string runId)
        {
            TriggeredJobRun triggeredJobRun = _triggeredJobsManager.GetJobRun(jobName, runId);

            if (triggeredJobRun != null)
            {
                return(Request.CreateResponse(HttpStatusCode.OK, triggeredJobRun));
            }

            return(Request.CreateResponse(HttpStatusCode.NotFound));
        }
예제 #6
0
        private void AssertTriggeredJobRun(ApplicationManager appManager, TriggeredJobRun actualTriggeredJobRun, string expectedStatus, string expectedOutput = null, string expectedError = null)
        {
            Assert.NotNull(actualTriggeredJobRun);
            Assert.Equal(expectedStatus, actualTriggeredJobRun.Status);
            Assert.NotNull(actualTriggeredJobRun.Duration);
            Assert.NotNull(actualTriggeredJobRun.EndTime);
            Assert.NotNull(actualTriggeredJobRun.Id);
            Assert.NotNull(actualTriggeredJobRun.StartTime);
            Assert.NotNull(actualTriggeredJobRun.Url);

            AssertUrlContentAsync(appManager, actualTriggeredJobRun.OutputUrl, expectedOutput).Wait();
        }
예제 #7
0
 internal TriggeredWebJobData(ResourceIdentifier id, string name, ResourceType resourceType, SystemData systemData, string kind, TriggeredJobRun latestRun, Uri historyUri, Uri schedulerLogsUri, string runCommand, Uri uri, Uri extraInfoUri, WebJobType?webJobType, string error, bool?usingSdk, IDictionary <string, BinaryData> settings) : base(id, name, resourceType, systemData, kind)
 {
     LatestRun        = latestRun;
     HistoryUri       = historyUri;
     SchedulerLogsUri = schedulerLogsUri;
     RunCommand       = runCommand;
     Uri          = uri;
     ExtraInfoUri = extraInfoUri;
     WebJobType   = webJobType;
     Error        = error;
     UsingSdk     = usingSdk;
     Settings     = settings;
 }
예제 #8
0
 internal TriggeredWebJobData(ResourceIdentifier id, string name, ResourceType type, SystemData systemData, string kind, TriggeredJobRun latestRun, string historyUrl, string schedulerLogsUrl, string runCommand, string url, string extraInfoUrl, WebJobType?webJobType, string error, bool?usingSdk, IDictionary <string, object> settings) : base(id, name, type, systemData, kind)
 {
     LatestRun        = latestRun;
     HistoryUrl       = historyUrl;
     SchedulerLogsUrl = schedulerLogsUrl;
     RunCommand       = runCommand;
     Url          = url;
     ExtraInfoUrl = extraInfoUrl;
     WebJobType   = webJobType;
     Error        = error;
     UsingSdk     = usingSdk;
     Settings     = settings;
 }
예제 #9
0
        private void VerifyTriggeredJobTriggers(ApplicationManager appManager, string jobName, int expectedNumberOfRuns, string expectedStatus, string expectedOutput = null, string expectedError = null, string arguments = null)
        {
            appManager.JobsManager.InvokeTriggeredJobAsync(jobName, arguments).Wait();

            WaitUntilAssertVerified(
                "verify triggered job run",
                TimeSpan.FromSeconds(20),
                () =>
            {
                TriggeredJobHistory triggeredJobHistory = appManager.JobsManager.GetTriggeredJobHistoryAsync(jobName).Result;
                Assert.NotNull(triggeredJobHistory);
                Assert.Equal(expectedNumberOfRuns, triggeredJobHistory.TriggeredJobRuns.Count());

                TriggeredJobRun triggeredJobRun = triggeredJobHistory.TriggeredJobRuns.FirstOrDefault();
                AssertTriggeredJobRun(appManager, triggeredJobRun, jobName, expectedStatus, expectedOutput, expectedError);
            });
        }
예제 #10
0
        public TriggeredJobHistory GetJobHistory(string jobName, string etag, out string currentETag)
        {
            currentETag = null;
            var triggeredJobRuns = new List <TriggeredJobRun>();

            DirectoryInfoBase[] jobRunsDirectories = GetJobRunsDirectories(jobName);
            if (jobRunsDirectories == null)
            {
                return(null);
            }

            bool isLatest = true;

            // Order runs by name (date) descending
            foreach (DirectoryInfoBase jobRunDirectory in jobRunsDirectories.OrderByDescending(j => j.Name))
            {
                TriggeredJobRun triggeredJobRun = BuildJobRun(jobRunDirectory, jobName, isLatest);
                if (triggeredJobRun != null)
                {
                    if (isLatest)
                    {
                        // The history state is determined by the most recent invocation,
                        // as previous ones are immutable (beind historical records).
                        currentETag = CalculateETag(triggeredJobRun);
                        if (currentETag == etag)
                        {
                            return(null);
                        }
                    }
                    triggeredJobRuns.Add(triggeredJobRun);
                    isLatest = false;
                }
            }

            if (triggeredJobRuns.Count == 0)
            {
                currentETag = string.Format(CultureInfo.CurrentCulture, "\"{0:x}-{1:x}\"",
                                            jobName.GetHashCode(), "EMPTY".GetHashCode());
            }

            return(new TriggeredJobHistory {
                TriggeredJobRuns = triggeredJobRuns
            });
        }
예제 #11
0
        private void OnSchedule(TriggeredJobSchedule triggeredJobSchedule)
        {
            bool invoked = false;

            try
            {
                string triggeredJobName = triggeredJobSchedule.TriggeredJob.Name;

                TriggeredJobRun latestTriggeredJobRun = _triggeredJobsManager.GetLatestJobRun(triggeredJobName);
                DateTime        lastRun = latestTriggeredJobRun != null ? latestTriggeredJobRun.StartTime : DateTime.Now.AddMinutes(-1);

                // Make sure we are on schedule
                // Check for the next occurence after the last run (as of now)
                // If it is still now, invoke the triggered job
                // If it's not now (in the future) reschedule the triggered job schedule starting with the last triggered job run
                TimeSpan currentSchedule = triggeredJobSchedule.Schedule.GetNextInterval(lastRun, ignoreMissed: true);
                if (currentSchedule == TimeSpan.Zero)
                {
                    _triggeredJobsManager.InvokeTriggeredJob(triggeredJobName, null, "Schedule - " + triggeredJobSchedule.Schedule);
                    invoked = true;
                }
                else
                {
                    triggeredJobSchedule.Reschedule(lastRun);
                    return;
                }
            }
            catch (ConflictException)
            {
                // Ignore as this is expected when running multiple instances
            }
            catch (Exception ex)
            {
                _traceFactory.GetTracer().TraceError(ex);
            }

            if (invoked)
            {
                triggeredJobSchedule.Logger.LogInformation("WebJob invoked");
            }

            triggeredJobSchedule.Reschedule(DateTime.Now);
        }
예제 #12
0
        private void VerifyTriggeredJobTriggers(ApplicationManager appManager, string jobName, int expectedNumberOfRuns, string expectedStatus, string expectedOutput = null, string expectedError = null, string arguments = null, bool scheduledTriggeredJob = false)
        {
            if (!scheduledTriggeredJob)
            {
                Uri runLocation = appManager.JobsManager.InvokeTriggeredJobAsync(jobName, arguments).Result;
                Assert.Contains("api/triggeredwebjobs", runLocation.AbsoluteUri);
                Assert.Contains("history", runLocation.AbsoluteUri);
            }

            try
            {
                WaitUntilAssertVerified(
                    "verify triggered job run",
                    TimeSpan.FromSeconds(30),
                    () =>
                {
                    TriggeredJobHistory triggeredJobHistory = appManager.JobsManager.GetTriggeredJobHistoryAsync(jobName).Result;
                    Assert.NotNull(triggeredJobHistory);
                    Assert.Equal(expectedNumberOfRuns, triggeredJobHistory.TriggeredJobRuns.Count());

                    TriggeredJobRun triggeredJobRun = triggeredJobHistory.TriggeredJobRuns.FirstOrDefault();
                    AssertTriggeredJobRun(appManager, triggeredJobRun, jobName, expectedStatus, expectedOutput, expectedError);
                });
            }
            catch
            {
                // On error trace the scheduler log if it is a scheduler job
                if (scheduledTriggeredJob)
                {
                    try
                    {
                        string schedulerLog = appManager.VfsManager.ReadAllText(JobsDataPath + "/triggered/" + jobName + "/job_scheduler.log");
                        TestTracer.Trace("Scheduler log - " + schedulerLog);
                    }
                    catch
                    {
                    }
                }

                throw;
            }
        }
예제 #13
0
        internal static TriggeredWebJobData DeserializeTriggeredWebJobData(JsonElement element)
        {
            Optional <string>          kind                       = default;
            ResourceIdentifier         id                         = default;
            string                     name                       = default;
            ResourceType               type                       = default;
            SystemData                 systemData                 = default;
            Optional <TriggeredJobRun> latestRun                  = default;
            Optional <Uri>             historyUrl                 = default;
            Optional <Uri>             schedulerLogsUrl           = default;
            Optional <string>          runCommand                 = default;
            Optional <Uri>             url                        = default;
            Optional <Uri>             extraInfoUrl               = default;
            Optional <WebJobType>      webJobType                 = default;
            Optional <string>          error                      = default;
            Optional <bool>            usingSdk                   = default;
            Optional <IDictionary <string, BinaryData> > settings = default;

            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("kind"))
                {
                    kind = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("id"))
                {
                    id = new ResourceIdentifier(property.Value.GetString());
                    continue;
                }
                if (property.NameEquals("name"))
                {
                    name = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("type"))
                {
                    type = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("systemData"))
                {
                    systemData = JsonSerializer.Deserialize <SystemData>(property.Value.ToString());
                    continue;
                }
                if (property.NameEquals("properties"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    foreach (var property0 in property.Value.EnumerateObject())
                    {
                        if (property0.NameEquals("latest_run"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            latestRun = TriggeredJobRun.DeserializeTriggeredJobRun(property0.Value);
                            continue;
                        }
                        if (property0.NameEquals("history_url"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                historyUrl = null;
                                continue;
                            }
                            historyUrl = new Uri(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("scheduler_logs_url"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                schedulerLogsUrl = null;
                                continue;
                            }
                            schedulerLogsUrl = new Uri(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("run_command"))
                        {
                            runCommand = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("url"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                url = null;
                                continue;
                            }
                            url = new Uri(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("extra_info_url"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                extraInfoUrl = null;
                                continue;
                            }
                            extraInfoUrl = new Uri(property0.Value.GetString());
                            continue;
                        }
                        if (property0.NameEquals("web_job_type"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            webJobType = property0.Value.GetString().ToWebJobType();
                            continue;
                        }
                        if (property0.NameEquals("error"))
                        {
                            error = property0.Value.GetString();
                            continue;
                        }
                        if (property0.NameEquals("using_sdk"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            usingSdk = property0.Value.GetBoolean();
                            continue;
                        }
                        if (property0.NameEquals("settings"))
                        {
                            if (property0.Value.ValueKind == JsonValueKind.Null)
                            {
                                property0.ThrowNonNullablePropertyIsNull();
                                continue;
                            }
                            Dictionary <string, BinaryData> dictionary = new Dictionary <string, BinaryData>();
                            foreach (var property1 in property0.Value.EnumerateObject())
                            {
                                dictionary.Add(property1.Name, BinaryData.FromString(property1.Value.GetRawText()));
                            }
                            settings = dictionary;
                            continue;
                        }
                    }
                    continue;
                }
            }
            return(new TriggeredWebJobData(id, name, type, systemData, kind.Value, latestRun.Value, historyUrl.Value, schedulerLogsUrl.Value, runCommand.Value, url.Value, extraInfoUrl.Value, Optional.ToNullable(webJobType), error.Value, Optional.ToNullable(usingSdk), Optional.ToDictionary(settings)));
        }