public async Task QueueJobs_Called_ReturnsJobs() { string specificationId = "1234"; string jobId = "3456"; IJobsApiClient jobsApiClient = Substitute.For <IJobsApiClient>(); JobManagementResiliencePolicies policies = new JobManagementResiliencePolicies { JobsApiClient = Policy.NoOpAsync() }; IMessengerService messengerService = Substitute.For <IMessengerService>(); ILogger logger = Substitute.For <ILogger>(); IEnumerable <Job> jobApiResponse = new List <Job> { new Job { Id = jobId } }; IEnumerable <JobCreateModel> jobCreateModel = new List <JobCreateModel> { new JobCreateModel { SpecificationId = specificationId } }; jobsApiClient .CreateJobs(jobCreateModel) .Returns(jobApiResponse); JobManagement jobManagement = new JobManagement(jobsApiClient, logger, policies, messengerService); //Act await jobManagement.QueueJobs(jobCreateModel); await jobsApiClient .Received(1) .CreateJobs(jobCreateModel); }
public async Task <IEnumerable <Job> > QueueJobs(IEnumerable <JobCreateModel> jobCreateModels) => await _jobsApiClientPolicy.ExecuteAsync(() => _jobsApiClient.CreateJobs(jobCreateModels));
public void CreateAllocationLineResultStatusUpdateJobs_GivenUpateModelWith10ProvidersAndMaxPartitionSizeOf2ButOnlyThreeJobsCreatedFromFive_ThrowsException() { //Arrange const string cacheKey = "cache-key"; Message message = new Message(); message.UserProperties.Add("jobId", jobId); ILogger logger = CreateLogger(); JobViewModel job = new JobViewModel { Id = jobId, SpecificationId = specificationId, InvokerUserDisplayName = "user-name", InvokerUserId = "user-id", CorrelationId = "coorelation-id", Properties = new Dictionary <string, string> { { "cache-key", cacheKey } }, JobDefinitionId = JobConstants.DefinitionNames.CreateInstructAllocationLineResultStatusUpdateJob }; UpdatePublishedAllocationLineResultStatusModel updateModel = new UpdatePublishedAllocationLineResultStatusModel { Status = AllocationLineStatus.Approved, Providers = CreateProviderAllocationLineResults() }; ApiResponse <JobViewModel> apiResponse = new ApiResponse <JobViewModel>(HttpStatusCode.OK, job); IJobsApiClient jobsApiClient = CreateJobsApiClient(); jobsApiClient .GetJobById(jobId) .Returns(apiResponse); IEnumerable <Job> newJobs = new[] { new Job(), new Job(), new Job() }; jobsApiClient .CreateJobs(Arg.Any <IEnumerable <JobCreateModel> >()) .Returns(newJobs); ICacheProvider cacheProvider = CreateCacheProvider(); cacheProvider .GetAsync <UpdatePublishedAllocationLineResultStatusModel>(Arg.Is(cacheKey)) .Returns(updateModel); IPublishedProviderResultsSettings settings = CreatePublishedProviderResultsSettings(); settings .UpdateAllocationLineResultStatusBatchCount .Returns(2); PublishedResultsService publishedResultsService = CreateResultsService(logger, jobsApiClient: jobsApiClient, cacheProvider: cacheProvider, publishedProviderResultsSettings: settings); //Act Func <Task> test = async() => await publishedResultsService.CreateAllocationLineResultStatusUpdateJobs(message); //Assert test .Should() .ThrowExactly <Exception>() .Which .Message .Should() .Be($"Only 3 jobs were created from 5 childJobs for parent job: '{job.Id}'"); logger .Received(1) .Error(Arg.Is($"Only 3 jobs were created from 5 childJobs for parent job: '{job.Id}'")); }
public async Task CreateAllocationLineResultStatusUpdateJobs_GivenUpateModelWith10ProvidersAndMaxPartitionSizeOf2_CreatesFiveChildJobs() { //Arrange const string cacheKey = "cache-key"; Message message = new Message(); message.UserProperties.Add("jobId", jobId); ILogger logger = CreateLogger(); JobViewModel job = new JobViewModel { Id = jobId, SpecificationId = specificationId, InvokerUserDisplayName = "user-name", InvokerUserId = "user-id", CorrelationId = "coorelation-id", Properties = new Dictionary <string, string> { { "cache-key", cacheKey } }, JobDefinitionId = JobConstants.DefinitionNames.CreateInstructAllocationLineResultStatusUpdateJob }; UpdatePublishedAllocationLineResultStatusModel updateModel = new UpdatePublishedAllocationLineResultStatusModel { Status = AllocationLineStatus.Approved, Providers = CreateProviderAllocationLineResults() }; ApiResponse <JobViewModel> apiResponse = new ApiResponse <JobViewModel>(HttpStatusCode.OK, job); IJobsApiClient jobsApiClient = CreateJobsApiClient(); jobsApiClient .GetJobById(jobId) .Returns(apiResponse); IEnumerable <Job> newJobs = new[] { new Job(), new Job(), new Job(), new Job(), new Job(), }; jobsApiClient .CreateJobs(Arg.Any <IEnumerable <JobCreateModel> >()) .Returns(newJobs); ICacheProvider cacheProvider = CreateCacheProvider(); cacheProvider .GetAsync <UpdatePublishedAllocationLineResultStatusModel>(Arg.Is(cacheKey)) .Returns(updateModel); IPublishedProviderResultsSettings settings = CreatePublishedProviderResultsSettings(); settings .UpdateAllocationLineResultStatusBatchCount .Returns(2); PublishedResultsService publishedResultsService = CreateResultsService(logger, jobsApiClient: jobsApiClient, cacheProvider: cacheProvider, publishedProviderResultsSettings: settings); //Act await publishedResultsService.CreateAllocationLineResultStatusUpdateJobs(message); //Assert await jobsApiClient .Received(1) .CreateJobs(Arg.Is <IEnumerable <JobCreateModel> >(m => m.Count() == 5)); await cacheProvider .Received(1) .RemoveAsync <UpdatePublishedAllocationLineResultStatusModel>(Arg.Is(cacheKey)); }
public async Task CreateAllocationLineResultStatusUpdateJobs_GivenUpateModelWith10ProvidersAndDefaultMaxPartitionSize_CreatesOneChildJob() { //Arrange const string cacheKey = "cache-key"; Message message = new Message(); message.UserProperties.Add("jobId", jobId); ILogger logger = CreateLogger(); JobViewModel job = new JobViewModel { Id = jobId, SpecificationId = specificationId, InvokerUserDisplayName = "user-name", InvokerUserId = "user-id", CorrelationId = "coorelation-id", Properties = new Dictionary <string, string> { { "cache-key", cacheKey } }, JobDefinitionId = JobConstants.DefinitionNames.CreateInstructAllocationLineResultStatusUpdateJob }; UpdatePublishedAllocationLineResultStatusModel updateModel = new UpdatePublishedAllocationLineResultStatusModel { Status = AllocationLineStatus.Approved, Providers = CreateProviderAllocationLineResults() }; ApiResponse <JobViewModel> apiResponse = new ApiResponse <JobViewModel>(HttpStatusCode.OK, job); IJobsApiClient jobsApiClient = CreateJobsApiClient(); jobsApiClient .GetJobById(jobId) .Returns(apiResponse); IEnumerable <Job> newJobs = new[] { new Job() }; jobsApiClient .CreateJobs(Arg.Any <IEnumerable <JobCreateModel> >()) .Returns(newJobs); ICacheProvider cacheProvider = CreateCacheProvider(); cacheProvider .GetAsync <UpdatePublishedAllocationLineResultStatusModel>(Arg.Is(cacheKey)) .Returns(updateModel); PublishedResultsService publishedResultsService = CreateResultsService(logger, jobsApiClient: jobsApiClient, cacheProvider: cacheProvider); //Act await publishedResultsService.CreateAllocationLineResultStatusUpdateJobs(message); //Assert await jobsApiClient .Received(1) .CreateJobs(Arg.Is <IEnumerable <JobCreateModel> >( m => m.First().Trigger.EntityId == jobId && m.First().Trigger.EntityType == "Job" && m.First().Trigger.Message == $"Triggered by parent job" && m.First().SpecificationId == specificationId && m.First().ParentJobId == jobId && m.First().InvokerUserId == job.InvokerUserId && m.First().InvokerUserDisplayName == job.InvokerUserDisplayName && m.First().CorrelationId == job.CorrelationId && !string.IsNullOrWhiteSpace(m.First().MessageBody))); await cacheProvider .Received(1) .RemoveAsync <UpdatePublishedAllocationLineResultStatusModel>(Arg.Is(cacheKey)); }
private async Task <IEnumerable <Job> > CreateGenerateAllocationJobs(JobViewModel parentJob, IEnumerable <IDictionary <string, string> > jobProperties) { HashSet <string> calculationsToAggregate = new HashSet <string>(); if (parentJob.JobDefinitionId == JobConstants.DefinitionNames.CreateInstructGenerateAggregationsAllocationJob) { string calculationAggregatesCacheKeyPrefix = $"{CacheKeys.CalculationAggregations}{parentJob.SpecificationId}"; await _cacheProvider.RemoveByPatternAsync(calculationAggregatesCacheKeyPrefix); IEnumerable <Models.Calcs.Calculation> calculations = await _calculationsRepository.GetCalculationsBySpecificationId(parentJob.SpecificationId); foreach (Models.Calcs.Calculation calculation in calculations) { IEnumerable <string> aggregateParameters = SourceCodeHelpers.GetCalculationAggregateFunctionParameters(calculation.Current.SourceCode); if (aggregateParameters.IsNullOrEmpty()) { continue; } foreach (string aggregateParameter in aggregateParameters) { Models.Calcs.Calculation referencedCalculation = calculations.FirstOrDefault(m => string.Equals(CalculationTypeGenerator.GenerateIdentifier(m.Name.Trim()), aggregateParameter.Trim(), StringComparison.InvariantCultureIgnoreCase)); if (referencedCalculation != null) { calculationsToAggregate.Add(aggregateParameter); } } } } IList <JobCreateModel> jobCreateModels = new List <JobCreateModel>(); Trigger trigger = new Trigger { EntityId = parentJob.Id, EntityType = nameof(Job), Message = $"Triggered by parent job with id: '{parentJob.Id}" }; int batchNumber = 1; int batchCount = jobProperties.Count(); string calcsToAggregate = string.Join(",", calculationsToAggregate); foreach (IDictionary <string, string> properties in jobProperties) { properties.Add("batch-number", batchNumber.ToString()); properties.Add("batch-count", batchCount.ToString()); properties.Add("calculations-to-aggregate", calcsToAggregate); JobCreateModel jobCreateModel = new JobCreateModel { InvokerUserDisplayName = parentJob.InvokerUserDisplayName, InvokerUserId = parentJob.InvokerUserId, JobDefinitionId = parentJob.JobDefinitionId == JobConstants.DefinitionNames.CreateInstructAllocationJob ? JobConstants.DefinitionNames.CreateAllocationJob : JobConstants.DefinitionNames.GenerateCalculationAggregationsJob, SpecificationId = parentJob.SpecificationId, Properties = properties, ParentJobId = parentJob.Id, Trigger = trigger, CorrelationId = parentJob.CorrelationId }; batchNumber++; jobCreateModels.Add(jobCreateModel); } return(await _jobsApiClientPolicy.ExecuteAsync(() => _jobsApiClient.CreateJobs(jobCreateModels))); }