public async Task UpdateJobStatus_ApiResponseSuccess_Runs() { //Arrange IJobsApiClient jobsApiClient = Substitute.For <IJobsApiClient>(); JobManagementResiliencePolicies policies = new JobManagementResiliencePolicies { JobsApiClient = Policy.NoOpAsync() }; IMessengerService messengerService = Substitute.For <IMessengerService>(); ILogger logger = Substitute.For <ILogger>(); ApiResponse <JobLog> jobLogApiResponse = new ApiResponse <JobLog>(HttpStatusCode.OK, new JobLog()); jobsApiClient .AddJobLog(Arg.Any <string>(), Arg.Any <JobLogUpdateModel>()) .Returns(jobLogApiResponse); JobLogUpdateModel updateModel = new JobLogUpdateModel(); JobManagement jobManagement = new JobManagement(jobsApiClient, logger, policies, messengerService); string jobId = "3456"; //Act await jobManagement.UpdateJobStatus(jobId, updateModel); //Assert await jobsApiClient .Received(1) .AddJobLog(jobId, updateModel); logger .Received(0) .Write(Arg.Any <LogEventLevel>(), Arg.Any <string>()); }
public async Task UpdateJobStatusInternal_ApiResponseFailure_Logs(ApiResponse <JobLog> jobLogApiResponse) { //Arrange IJobsApiClient jobsApiClient = Substitute.For <IJobsApiClient>(); JobManagementResiliencePolicies policies = new JobManagementResiliencePolicies { JobsApiClient = Policy.NoOpAsync() }; IMessengerService messengerService = Substitute.For <IMessengerService>(); ILogger logger = Substitute.For <ILogger>(); jobsApiClient .AddJobLog(Arg.Any <string>(), Arg.Any <JobLogUpdateModel>()) .Returns(jobLogApiResponse); JobLogUpdateModel updateModel = new JobLogUpdateModel(); JobManagement jobManagement = new JobManagement(jobsApiClient, logger, policies, messengerService); string jobId = "3456"; //Act await jobManagement.UpdateJobStatus(jobId, updateModel); //Assert await jobsApiClient .Received(1) .AddJobLog(jobId, updateModel); logger .Received(1) .Write(LogEventLevel.Error, $"Failed to add a job log for job id '{jobId}'"); }
public async Task AddJobLog_Called_ReturnsJobLog() { string jobId = "5678"; IJobsApiClient jobsApiClient = Substitute.For <IJobsApiClient>(); JobManagementResiliencePolicies policies = new JobManagementResiliencePolicies { JobsApiClient = Policy.NoOpAsync() }; IMessengerService messengerService = Substitute.For <IMessengerService>(); ILogger logger = Substitute.For <ILogger>(); JobLog jobLog = new JobLog { JobId = jobId }; ApiResponse <JobLog> jobLogApiResponse = new ApiResponse <JobLog>(HttpStatusCode.OK, jobLog); JobLogUpdateModel jobLogUpdateModel = new JobLogUpdateModel(); jobsApiClient .AddJobLog(jobId, jobLogUpdateModel) .Returns(jobLogApiResponse); JobManagement jobManagement = new JobManagement(jobsApiClient, logger, policies, messengerService); //Act JobLog result = await jobManagement.AddJobLog(jobId, jobLogUpdateModel); Assert.AreEqual(result, jobLog); await jobsApiClient .Received(1) .AddJobLog(jobId, jobLogUpdateModel); }
public async Task AddJobLog_GivenJobNotFound_ReturnsNotFoundResult() { //Arrange string jobId = "job-id-1"; JobLogUpdateModel jobLogUpdateModel = new JobLogUpdateModel(); IJobRepository jobRepository = CreateJobRepository(); jobRepository .GetJobById(Arg.Is(jobId)) .Returns((Job)null); ILogger logger = CreateLogger(); JobManagementService jobManagementService = CreateJobManagementService(jobRepository: jobRepository, logger: logger); //Act IActionResult actionResult = await jobManagementService.AddJobLog(jobId, jobLogUpdateModel); //Assert actionResult .Should() .BeAssignableTo <NotFoundObjectResult>() .Which .Value .Should() .Be($"A job could not be found for job id: '{jobId}'"); logger .Received(1) .Error($"A job could not be found for job id: '{jobId}'"); }
public Task <ApiResponse <JobLog> > AddJobLog(string jobId, JobLogUpdateModel jobLogUpdateModel) { if (!_jobs.ContainsKey(jobId)) { throw new Exception("Job not found"); } if (!_jobLogs.ContainsKey(jobId)) { _jobLogs.Add(jobId, new List <JobLog>()); } Job job = _jobs[jobId]; JobLog jobLog = new JobLog() { CompletedSuccessfully = jobLogUpdateModel.CompletedSuccessfully, Id = Guid.NewGuid().ToString(), ItemsFailed = jobLogUpdateModel.ItemsFailed, ItemsProcessed = jobLogUpdateModel.ItemsProcessed, ItemsSucceeded = jobLogUpdateModel.ItemsSucceeded, JobId = jobId, Outcome = jobLogUpdateModel.Outcome, Timestamp = DateTime.UtcNow, }; if (job.RunningStatus == RunningStatus.Queued) { job.RunningStatus = RunningStatus.InProgress; } _jobLogs[jobId].Add(jobLog); return(Task.FromResult(new ApiResponse <JobLog>(System.Net.HttpStatusCode.OK, jobLog))); }
public async Task <JobLog> AddJobLog(string jobId, JobLogUpdateModel jobLogUpdateModel) { ApiResponse <JobLog> jobLogResponse = await _jobsApiClientPolicy.ExecuteAsync(() => _jobsApiClient.AddJobLog(jobId, jobLogUpdateModel)); JobLog jobLog = jobLogResponse?.Content; return(jobLog); }
public async Task <ApiResponse <JobLog> > AddJobLog(string jobId, JobLogUpdateModel jobLogUpdateModel) { Guard.IsNullOrWhiteSpace(jobId, nameof(jobId)); Guard.ArgumentNotNull(jobLogUpdateModel, nameof(jobLogUpdateModel)); return(await PostAsync <JobLog, JobLogUpdateModel>($"jobs/{jobId}/logs", jobLogUpdateModel)); }
public async Task AddJobLog_GivenJobUpdated_EnsuresNewJobLogCreated() { //Arrange string jobId = "job-id-1"; JobLogUpdateModel jobLogUpdateModel = new JobLogUpdateModel { CompletedSuccessfully = false, Outcome = "outcome", ItemsFailed = 40, ItemsProcessed = 100, ItemsSucceeded = 60 }; Job job = new Job { Id = jobId, RunningStatus = RunningStatus.InProgress }; IJobRepository jobRepository = CreateJobRepository(); jobRepository .GetJobById(Arg.Is(jobId)) .Returns(job); jobRepository .UpdateJob(Arg.Is(job)) .Returns(HttpStatusCode.OK); jobRepository .CreateJobLog(Arg.Any <JobLog>()) .Returns(HttpStatusCode.OK); ILogger logger = CreateLogger(); JobManagementService jobManagementService = CreateJobManagementService(jobRepository: jobRepository, logger: logger); //Act IActionResult actionResult = await jobManagementService.AddJobLog(jobId, jobLogUpdateModel); //Assert actionResult .Should() .BeAssignableTo <OkObjectResult>(); await jobRepository .Received(1) .CreateJobLog(Arg.Is <JobLog>(m => !string.IsNullOrWhiteSpace(m.Id) && m.JobId == jobId && m.ItemsProcessed == 100 && m.ItemsFailed == 40 && m.ItemsSucceeded == 60 && m.CompletedSuccessfully == false && m.Timestamp.Date == DateTimeOffset.Now.ToLocalTime().Date)); }
public async Task UpdateJobStatus(string jobId, JobLogUpdateModel jobLogUpdateModel) { ApiResponse <JobLog> jobLogResponse = await _jobsApiClientPolicy.ExecuteAsync(() => _jobsApiClient.AddJobLog(jobId, jobLogUpdateModel)); if (jobLogResponse?.Content == null) { _logger.Write(LogEventLevel.Error, $"Failed to add a job log for job id '{jobId}'"); } }
public async Task AddJobLog() { string id = NewRandomString(); JobLogUpdateModel jobLogUpdateModel = new JobLogUpdateModel(); await AssertPostRequest($"jobs/{id}/logs", jobLogUpdateModel, new JobLog(), () => _client.AddJobLog(id, jobLogUpdateModel)); }
public async Task UpdateJobStatus(string jobId, int percentComplete = 0, bool?completedSuccessfully = null, string outcome = null) { JobLogUpdateModel jobLogUpdateModel = new JobLogUpdateModel { CompletedSuccessfully = completedSuccessfully, ItemsProcessed = percentComplete, Outcome = outcome }; await UpdateJobStatus(jobId, jobLogUpdateModel); }
public async Task AddJobLog_GivenJobUpdatedButCreatingJobLogFails_ThrowsExceptionDoesNotSendNotification() { //Arrange string jobId = "job-id-1"; JobLogUpdateModel jobLogUpdateModel = new JobLogUpdateModel { CompletedSuccessfully = false, Outcome = "outcome", ItemsFailed = 40, ItemsProcessed = 100, ItemsSucceeded = 60 }; Job job = new Job { Id = jobId, RunningStatus = RunningStatus.InProgress }; IJobRepository jobRepository = CreateJobRepository(); jobRepository .GetJobById(Arg.Is(jobId)) .Returns(job); jobRepository .UpdateJob(Arg.Is(job)) .Returns(HttpStatusCode.OK); jobRepository .CreateJobLog(Arg.Any <JobLog>()) .Returns(HttpStatusCode.BadRequest); INotificationService notificationService = CreateNotificationsService(); JobManagementService jobManagementService = CreateJobManagementService(jobRepository: jobRepository, notificationService: notificationService); //Act Func <Task> test = async() => await jobManagementService.AddJobLog(jobId, jobLogUpdateModel); //Assert test .Should() .ThrowExactly <Exception>() .Which.Message .Should() .Be($"Failed to create a job log for job id: '{jobId}'"); await notificationService .DidNotReceive() .SendNotification(Arg.Any <JobNotification>()); }
public async Task UpdateJobStatus(string jobId, int totalItemsCount, int failedItemsCount, bool?completedSuccessfully = null, string outcome = null) { JobLogUpdateModel jobLogUpdateModel = new JobLogUpdateModel { CompletedSuccessfully = completedSuccessfully, ItemsProcessed = totalItemsCount, ItemsFailed = failedItemsCount, ItemsSucceeded = totalItemsCount - failedItemsCount, Outcome = outcome }; await UpdateJobStatus(jobId, jobLogUpdateModel); }
public async Task AddJobLog_GivenJobFoundAndSetToInProgressButFailedToUpdateJob_ReturnsInternalServerErrorResult() { //Arrange string jobId = "job-id-1"; JobLogUpdateModel jobLogUpdateModel = new JobLogUpdateModel(); Job job = new Job { Id = jobId, RunningStatus = RunningStatus.Queued }; IJobRepository jobRepository = CreateJobRepository(); jobRepository .GetJobById(Arg.Is(jobId)) .Returns(job); jobRepository .GetLatestJobBySpecificationIdAndDefinitionId(Arg.Any <string>(), Arg.Any <string>()) .Returns(job); jobRepository .UpdateJob(Arg.Is(job)) .Returns(HttpStatusCode.BadRequest); ILogger logger = CreateLogger(); JobManagementService jobManagementService = CreateJobManagementService(jobRepository: jobRepository, logger: logger); //Act IActionResult actionResult = await jobManagementService.AddJobLog(jobId, jobLogUpdateModel); //Assert actionResult .Should() .BeAssignableTo <InternalServerErrorResult>() .Which .Value .Should() .Be($"Failed to update job id: '{jobId}' with status code '400'"); logger .Received(1) .Error($"Failed to update job id: '{jobId}' with status code '400'"); job .RunningStatus .Should() .Be(RunningStatus.InProgress); }
public async Task AddJobLog_GivenJobFoundAndSetToCompletedAndIsFailed_EnsuresJobIsUpdatedWithCorrectValues() { //Arrange string jobId = "job-id-1"; JobLogUpdateModel jobLogUpdateModel = new JobLogUpdateModel { CompletedSuccessfully = false, Outcome = "outcome", OutcomeType = NewRandomOutcomeType() }; Job job = new Job { Id = jobId, RunningStatus = RunningStatus.InProgress }; IJobRepository jobRepository = CreateJobRepository(); jobRepository .GetJobById(Arg.Is(jobId)) .Returns(job); jobRepository .UpdateJob(Arg.Is(job)) .Returns(HttpStatusCode.OK); jobRepository .CreateJobLog(Arg.Any <JobLog>()) .Returns(HttpStatusCode.OK); ILogger logger = CreateLogger(); JobManagementService jobManagementService = CreateJobManagementService(jobRepository: jobRepository, logger: logger); //Act IActionResult actionResult = await jobManagementService.AddJobLog(jobId, jobLogUpdateModel); //Assert actionResult .Should() .BeAssignableTo <OkObjectResult>(); job.RunningStatus.Should().Be(RunningStatus.Completed); job.Completed.Should().NotBeNull(); job.CompletionStatus.Should().Be(CompletionStatus.Failed); job.Outcome.Should().Be("outcome"); job.OutcomeType.Should().Be(jobLogUpdateModel.OutcomeType); }
public async Task <IResultModel> Update(JobLogUpdateModel model) { var entity = await _repository.FirstAsync(model.Id); if (entity == null) { return(ResultModel.NotExists); } _mapper.Map(model, entity); var result = await _repository.UpdateAsync(entity); return(ResultModel.Result(result)); }
private async Task UpdateJobStatus(string jobId, bool?completedSuccessfully, int percentComplete, string outcome = null) { JobLogUpdateModel jobLogUpdateModel = new JobLogUpdateModel { CompletedSuccessfully = completedSuccessfully, ItemsProcessed = percentComplete, Outcome = outcome }; ApiResponse <JobLog> jobLogResponse = await _jobsApiClientPolicy.ExecuteAsync(() => _jobsApiClient.AddJobLog(jobId, jobLogUpdateModel)); if (jobLogResponse == null || jobLogResponse.Content == null) { _logger.Error($"Failed to add a job log for job id '{jobId}'"); } }
public Task <IResultModel> Update(JobLogUpdateModel model) { return(_service.Update(model)); }
public async Task <IActionResult> AddJobLog(string jobId, JobLogUpdateModel jobLogUpdateModel) { Guard.IsNullOrWhiteSpace(jobId, nameof(jobId)); Guard.ArgumentNotNull(jobLogUpdateModel, nameof(jobLogUpdateModel)); Job job = await _jobsRepositoryPolicy.ExecuteAsync(() => _jobRepository.GetJobById(jobId)); if (job == null) { string error = $"A job could not be found for job id: '{jobId}'"; _logger.Error(error); return(new NotFoundObjectResult(error)); } bool needToSaveJob = false; if (jobLogUpdateModel.CompletedSuccessfully.HasValue) { bool completedSuccessfully = jobLogUpdateModel.CompletedSuccessfully.Value; job.Completed = DateTimeOffset.UtcNow; job.RunningStatus = RunningStatus.Completed; job.CompletionStatus = completedSuccessfully ? CompletionStatus.Succeeded : CompletionStatus.Failed; job.OutcomeType = GetCompletedJobOutcomeType(jobLogUpdateModel); job.Outcome = jobLogUpdateModel.Outcome; needToSaveJob = true; } else { if (job.RunningStatus != RunningStatus.InProgress) { job.RunningStatus = RunningStatus.InProgress; needToSaveJob = true; } } if (needToSaveJob) { HttpStatusCode statusCode = await UpdateJob(job); if (!statusCode.IsSuccess()) { string error = $"Failed to update job id: '{jobId}' with status code '{(int)statusCode}'"; _logger.Error(error); return(new InternalServerErrorResult(error)); } } JobLog jobLog = new JobLog { Id = Guid.NewGuid().ToString(), JobId = jobId, ItemsProcessed = jobLogUpdateModel.ItemsProcessed, ItemsSucceeded = jobLogUpdateModel.ItemsSucceeded, ItemsFailed = jobLogUpdateModel.ItemsFailed, OutcomeType = jobLogUpdateModel.OutcomeType, Outcome = jobLogUpdateModel.Outcome, CompletedSuccessfully = jobLogUpdateModel.CompletedSuccessfully, Timestamp = DateTimeOffset.UtcNow }; HttpStatusCode createJobLogStatus = await _jobsRepositoryPolicy.ExecuteAsync(() => _jobRepository.CreateJobLog(jobLog)); if (!createJobLogStatus.IsSuccess()) { string error = $"Failed to create a job log for job id: '{jobId}'"; _logger.Error(error); throw new Exception(error); } await SendJobLogNotification(job, jobLog); return(new OkObjectResult(jobLog)); }
public async Task AddJobLog_GivenJobUpdated_EnsuresNewNotificationIsSent() { //Arrange string jobId = "job-id-1"; JobLogUpdateModel jobLogUpdateModel = new JobLogUpdateModel { CompletedSuccessfully = false, Outcome = "outcome", ItemsFailed = 40, ItemsProcessed = 100, ItemsSucceeded = 60 }; Job job = new Job { Id = jobId, RunningStatus = RunningStatus.InProgress, JobDefinitionId = "job-definition-id", InvokerUserDisplayName = "authorName", InvokerUserId = "authorId", ItemCount = 100, SpecificationId = "spec-id-1", Trigger = new Trigger { EntityId = "spec-id-1", EntityType = "Specification", Message = "allocating" } }; IJobRepository jobRepository = CreateJobRepository(); jobRepository .GetJobById(Arg.Is(jobId)) .Returns(job); jobRepository .UpdateJob(Arg.Is(job)) .Returns(HttpStatusCode.OK); jobRepository .CreateJobLog(Arg.Any <JobLog>()) .Returns(HttpStatusCode.OK); ILogger logger = CreateLogger(); INotificationService notificationService = CreateNotificationsService(); JobManagementService jobManagementService = CreateJobManagementService(jobRepository: jobRepository, logger: logger, notificationService: notificationService); //Act IActionResult actionResult = await jobManagementService.AddJobLog(jobId, jobLogUpdateModel); //Assert actionResult .Should() .BeAssignableTo <OkObjectResult>(); await notificationService .Received(1) .SendNotification(Arg.Is <JobNotification>(m => m.JobId == jobId && m.JobType == "job-definition-id" && m.CompletionStatus == CompletionStatus.Failed && m.InvokerUserDisplayName == "authorName" && m.InvokerUserId == "authorId" && m.ItemCount == 100 && m.Outcome == "outcome" && m.OverallItemsFailed == 40 && m.OverallItemsProcessed == 100 && m.OverallItemsSucceeded == 60 && m.ParentJobId == null && m.SpecificationId == "spec-id-1" && m.StatusDateTime.Date == DateTimeOffset.Now.ToLocalTime().Date&& string.IsNullOrWhiteSpace(m.SupersededByJobId) && m.Trigger.EntityId == "spec-id-1" && m.Trigger.EntityType == "Specification" && m.Trigger.Message == "allocating" && m.RunningStatus == RunningStatus.Completed )); }
public async Task AddJobLog_GivenJobUpdatedAndCompletedSuccessfully_EnsuresLatestCacheIsUpdated() { //Arrange string jobId = "job-id-1"; DateTimeOffset lastUpdated = new RandomDateTime(); List <Outcome> outcomes = new List <Outcome> { new Outcome { Description = "outcome-1" } }; string specificationId = "spec-id-1"; string jobDefinitionId = "job-definition-id"; JobLogUpdateModel jobLogUpdateModel = new JobLogUpdateModel { CompletedSuccessfully = true, Outcome = "outcome", ItemsFailed = 40, ItemsProcessed = 100, ItemsSucceeded = 60 }; Job job = new Job { Id = jobId, RunningStatus = RunningStatus.InProgress, JobDefinitionId = jobDefinitionId, InvokerUserDisplayName = "authorName", InvokerUserId = "authorId", LastUpdated = lastUpdated, ItemCount = 100, SpecificationId = specificationId, Trigger = new Trigger { EntityId = "spec-id-1", EntityType = "Specification", Message = "allocating" }, Outcomes = outcomes }; IJobRepository jobRepository = CreateJobRepository(); jobRepository .GetJobById(Arg.Is(jobId)) .Returns(job); jobRepository .UpdateJob(Arg.Is(job)) .Returns(HttpStatusCode.OK); jobRepository .CreateJobLog(Arg.Any <JobLog>()) .Returns(HttpStatusCode.OK); jobRepository .GetLatestJobBySpecificationIdAndDefinitionId(Arg.Is(specificationId), Arg.Is(jobDefinitionId)) .Returns(job); ILogger logger = CreateLogger(); INotificationService notificationService = CreateNotificationsService(); ICacheProvider cacheProvider = CreateCacheProvider(); JobManagementService jobManagementService = CreateJobManagementService( jobRepository: jobRepository, logger: logger, notificationService: notificationService, cacheProvider: cacheProvider); //Act IActionResult actionResult = await jobManagementService.AddJobLog(jobId, jobLogUpdateModel); //Assert actionResult .Should() .BeAssignableTo <OkObjectResult>(); await notificationService .Received(1) .SendNotification(Arg.Is <JobSummary>(m => m.JobId == jobId && m.JobType == "job-definition-id" && m.CompletionStatus == CompletionStatus.Succeeded && m.InvokerUserDisplayName == "authorName" && m.InvokerUserId == "authorId" && m.ItemCount == 100 && m.Outcome == "outcome" && m.OverallItemsFailed == 40 && m.OverallItemsProcessed == 100 && m.OverallItemsSucceeded == 60 && m.ParentJobId == null && m.SpecificationId == "spec-id-1" && string.IsNullOrWhiteSpace(m.SupersededByJobId) && m.Trigger.EntityId == "spec-id-1" && m.Trigger.EntityType == "Specification" && m.Trigger.Message == "allocating" && m.RunningStatus == RunningStatus.Completed && m.LastUpdated == lastUpdated && m.Outcomes.SequenceEqual(outcomes) && m.OutcomeType == OutcomeType.Succeeded )); string cacheKey = $"{CacheKeys.LatestJobs}{job.SpecificationId}:{job.JobDefinitionId}"; string latestSuccessfulJobCacheKey = $"{CacheKeys.LatestSuccessfulJobs}{job.SpecificationId}:{job.JobDefinitionId}"; await cacheProvider .Received(1) .SetAsync(cacheKey, Arg.Is <Job>(_ => _.Id == jobId)); await cacheProvider .Received(1) .SetAsync(latestSuccessfulJobCacheKey, Arg.Is <Job>(_ => _.Id == jobId)); }
public async Task AddJobLog_GivenJobUpdatedAndCompletedUnsuccesfully_EnsuresLatestCacheIsNotUpdated(CompletionStatus completionStatus) { //Arrange string jobId = "job-id-1"; DateTimeOffset lastUpdated = new RandomDateTime(); List <Outcome> outcomes = new List <Outcome> { new Outcome { Description = "outcome-1" } }; string specificationId = "spec-id-1"; string jobDefinitionId = "job-definition-id"; JobLogUpdateModel jobLogUpdateModel = new JobLogUpdateModel { CompletedSuccessfully = false, Outcome = "outcome", ItemsFailed = 40, ItemsProcessed = 100, ItemsSucceeded = 60 }; Job job = new Job { Id = jobId, RunningStatus = RunningStatus.InProgress, JobDefinitionId = jobDefinitionId, InvokerUserDisplayName = "authorName", InvokerUserId = "authorId", LastUpdated = lastUpdated, ItemCount = 100, SpecificationId = specificationId, Trigger = new Trigger { EntityId = "spec-id-1", EntityType = "Specification", Message = "allocating" }, Outcomes = outcomes }; Job completedJob = new Job { Id = jobId, RunningStatus = RunningStatus.Completed, JobDefinitionId = jobDefinitionId, InvokerUserDisplayName = "authorName", InvokerUserId = "authorId", LastUpdated = lastUpdated, ItemCount = 100, SpecificationId = specificationId, Trigger = new Trigger { EntityId = "spec-id-1", EntityType = "Specification", Message = "allocating" }, Outcomes = outcomes, CompletionStatus = completionStatus, }; IJobRepository jobRepository = CreateJobRepository(); jobRepository .GetJobById(Arg.Is(jobId)) .Returns(job); jobRepository .UpdateJob(Arg.Is(job)) .Returns(HttpStatusCode.OK); jobRepository .CreateJobLog(Arg.Any <JobLog>()) .Returns(HttpStatusCode.OK); jobRepository .GetLatestJobBySpecificationIdAndDefinitionId(Arg.Is(specificationId), Arg.Is(jobDefinitionId)) .Returns(completedJob); ILogger logger = CreateLogger(); ICacheProvider cacheProvider = CreateCacheProvider(); JobManagementService jobManagementService = CreateJobManagementService( jobRepository: jobRepository, logger: logger, cacheProvider: cacheProvider); //Act IActionResult actionResult = await jobManagementService.AddJobLog(jobId, jobLogUpdateModel); //Assert actionResult .Should() .BeAssignableTo <OkObjectResult>(); string cacheKey = $"{CacheKeys.LatestJobs}{job.SpecificationId}:{job.JobDefinitionId}"; string latestSuccessfulJobCacheKey = $"{CacheKeys.LatestSuccessfulJobs}{job.SpecificationId}:{job.JobDefinitionId}"; await cacheProvider .Received(1) .SetAsync(cacheKey, Arg.Is <Job>(_ => _.Id == jobId)); await cacheProvider .Received(0) .SetAsync(latestSuccessfulJobCacheKey, Arg.Is <Job>(_ => _.Id == jobId)); }
public async Task UpdateAllocations(Message message) { Guard.ArgumentNotNull(message, nameof(message)); JobViewModel job = null; if (!message.UserProperties.ContainsKey("jobId")) { _logger.Error("Missing parent job id to instruct generating allocations"); return; } string jobId = message.UserProperties["jobId"].ToString(); ApiResponse <JobViewModel> response = await _jobsApiClientPolicy.ExecuteAsync(() => _jobsApiClient.GetJobById(jobId)); if (response == null || response.Content == null) { _logger.Error($"Could not find the parent job with job id: '{jobId}'"); throw new Exception($"Could not find the parent job with job id: '{jobId}'"); } job = response.Content; if (job.CompletionStatus.HasValue) { _logger.Information($"Received job with id: '{job.Id}' is already in a completed state with status {job.CompletionStatus.ToString()}"); return; } await _jobsApiClientPolicy.ExecuteAsync(() => _jobsApiClient.AddJobLog(jobId, new Common.ApiClient.Jobs.Models.JobLogUpdateModel())); IDictionary <string, string> properties = message.BuildMessageProperties(); string specificationId = message.UserProperties["specification-id"].ToString(); BuildProject buildProject = await GetBuildProjectForSpecificationId(specificationId); if (message.UserProperties.ContainsKey("ignore-save-provider-results")) { properties.Add("ignore-save-provider-results", "true"); } string cacheKey = ""; if (message.UserProperties.ContainsKey("provider-cache-key")) { cacheKey = message.UserProperties["provider-cache-key"].ToString(); } else { cacheKey = $"{CacheKeys.ScopedProviderSummariesPrefix}{specificationId}"; } bool summariesExist = await _cacheProvider.KeyExists <ProviderSummary>(cacheKey); long totalCount = await _cacheProvider.ListLengthAsync <ProviderSummary>(cacheKey); bool refreshCachedScopedProviders = false; if (summariesExist) { IEnumerable <string> scopedProviderIds = await _providerResultsRepository.GetScopedProviderIds(specificationId); if (scopedProviderIds.Count() != totalCount) { refreshCachedScopedProviders = true; } else { IEnumerable <ProviderSummary> cachedScopedSummaries = await _cacheProvider.ListRangeAsync <ProviderSummary>(cacheKey, 0, (int)totalCount); IEnumerable <string> differences = scopedProviderIds.Except(cachedScopedSummaries.Select(m => m.Id)); refreshCachedScopedProviders = differences.AnyWithNullCheck(); } } if (!summariesExist || refreshCachedScopedProviders) { totalCount = await _providerResultsRepository.PopulateProviderSummariesForSpecification(specificationId); } const string providerSummariesPartitionIndex = "provider-summaries-partition-index"; const string providerSummariesPartitionSize = "provider-summaries-partition-size"; properties.Add(providerSummariesPartitionSize, _engineSettings.MaxPartitionSize.ToString()); properties.Add("provider-cache-key", cacheKey); properties.Add("specification-id", specificationId); IList <IDictionary <string, string> > allJobProperties = new List <IDictionary <string, string> >(); for (int partitionIndex = 0; partitionIndex < totalCount; partitionIndex += _engineSettings.MaxPartitionSize) { if (properties.ContainsKey(providerSummariesPartitionIndex)) { properties[providerSummariesPartitionIndex] = partitionIndex.ToString(); } else { properties.Add(providerSummariesPartitionIndex, partitionIndex.ToString()); } IDictionary <string, string> jobProperties = new Dictionary <string, string>(); foreach (KeyValuePair <string, string> item in properties) { jobProperties.Add(item.Key, item.Value); } allJobProperties.Add(jobProperties); } await _specificationsRepository.UpdateCalculationLastUpdatedDate(specificationId); try { if (!allJobProperties.Any()) { _logger.Information($"No scoped providers set for specification '{specificationId}'"); JobLogUpdateModel jobCompletedLog = new JobLogUpdateModel { CompletedSuccessfully = true, Outcome = "Calculations not run as no scoped providers set for specification" }; await _jobsApiClientPolicy.ExecuteAsync(() => _jobsApiClient.AddJobLog(job.Id, jobCompletedLog)); return; } IEnumerable <Job> newJobs = await CreateGenerateAllocationJobs(job, allJobProperties); int newJobsCount = newJobs.Count(); int batchCount = allJobProperties.Count(); if (newJobsCount != batchCount) { throw new Exception($"Only {newJobsCount} child jobs from {batchCount} were created with parent id: '{job.Id}'"); } else { _logger.Information($"{newJobsCount} child jobs were created for parent id: '{job.Id}'"); } } catch (Exception ex) { _logger.Error(ex.Message); throw new Exception($"Failed to create child jobs for parent job: '{job.Id}'"); } }
private async Task AddJobLog(JobLogUpdateModel jobLog, string jobId) { await _jobs.AddJobLog(jobId, jobLog); }
public async Task AddJobLog_WhenNoOutcomeTypeIsSuppliedInTheViewModelItIsDeterminedByTheJobLogDetails(JobLogUpdateModel jobLogUpdateModel, OutcomeType?expectedOutcomeType) { //Arrange string jobId = "job-id-1"; Job job = new Job { Id = jobId, RunningStatus = RunningStatus.InProgress }; IJobRepository jobRepository = CreateJobRepository(); jobRepository .GetJobById(Arg.Is(jobId)) .Returns(job); jobRepository .UpdateJob(Arg.Is(job)) .Returns(HttpStatusCode.OK); jobRepository .CreateJobLog(Arg.Any <JobLog>()) .Returns(HttpStatusCode.OK); ILogger logger = CreateLogger(); JobManagementService jobManagementService = CreateJobManagementService(jobRepository: jobRepository, logger: logger); //Act IActionResult actionResult = await jobManagementService.AddJobLog(jobId, jobLogUpdateModel); //Assert actionResult .Should() .BeAssignableTo <OkObjectResult>(); job.RunningStatus.Should().Be(RunningStatus.Completed); job.Completed.Should().NotBeNull(); job.OutcomeType.Should().Be(expectedOutcomeType); }
private async Task AddJobTracking(string jobId, JobLogUpdateModel tracking) { await _jobManagement.AddJobLog(jobId, tracking); }
public async Task <IActionResult> UpdateJobStatusLog([FromRoute] string jobId, [FromBody] JobLogUpdateModel job) { return(await _jobManagementService.AddJobLog(jobId, job)); }