private Task ConsumeSpecificationInformation(CancellationToken cancellationToken,
                                                     dynamic context,
                                                     IEnumerable <MergeSpecificationRequest> items)
        {
            ConcurrentDictionary <string, FundingPeriod> fundingPeriods = ((MergeContext)context).FundingPeriods;

            foreach (MergeSpecificationRequest mergeSpecificationRequest in items)
            {
                SpecificationInformation requestSpecificationInformation = mergeSpecificationRequest.SpecificationInformation;

                _logger.Information($"Merging specification information {requestSpecificationInformation.Name} for provider id {mergeSpecificationRequest.ProviderId}");

                ProviderWithResultsForSpecifications providerWithResultsForSpecifications = GetProviderWithResultsForSpecificationsForProviderId(mergeSpecificationRequest.ProviderId);

                SpecificationInformation specificationInformation = new SpecificationInformation
                {
                    Id               = requestSpecificationInformation.Id,
                    Name             = requestSpecificationInformation.Name,
                    LastEditDate     = requestSpecificationInformation.LastEditDate,
                    FundingPeriodId  = requestSpecificationInformation.FundingPeriodId,
                    FundingPeriodEnd = fundingPeriods.TryGetValue(requestSpecificationInformation.FundingPeriodId, out FundingPeriod fundingPeriod) ? fundingPeriod.EndDate : (DateTimeOffset?)null
                };

                providerWithResultsForSpecifications.MergeSpecificationInformation(specificationInformation);
            }

            return(Task.CompletedTask);
        }
        public async Task MergeSpecificationInformationMergesCreatesNewMissingProviderWithResultsForSpecificationsForSpecificProviderIdsWhenSupplied()
        {
            string jobId      = NewRandomString();
            string providerId = NewRandomString();

            SpecificationInformation             specificationInformation = NewSpecificationInformation();
            MergeSpecificationInformationRequest mergeRequest             = NewMergeSpecificationInformationRequest(_ => _.WithSpecificationInformation(specificationInformation)
                                                                                                                    .WithProviderIds(providerId));

            DateTimeOffset expectedFundingPeriodEndDate = NewRandomDateTime();

            GivenTheFundingPeriodEndDate(specificationInformation.FundingPeriodId, expectedFundingPeriodEndDate);

            Message message = NewMessage(_ => _.WithUserProperty(JobId, jobId)
                                         .WithUserProperty(ProviderId, providerId)
                                         .WithMessageBody(mergeRequest.AsJsonBytes()));

            await WhenTheSpecificationInformationIsMerged(message);

            ThenTheJobTrackingWasStarted(jobId);

            SpecificationInformation expectedSpecificationInformation = specificationInformation.DeepCopy();

            expectedSpecificationInformation.FundingPeriodEnd = expectedFundingPeriodEndDate;

            AndTheProviderWithResultsForSpecificationsWasUpserted(_ => _.Id == providerId &&
                                                                  HasEquivalentSpecificationInformation(_, expectedSpecificationInformation));
            AndTheJobTrackingWasCompleted(jobId);
        }
Beispiel #3
0
        private async Task MergeSpecificationInformationForProviderBatch(SpecificationInformation specificationInformation,
                                                                         IEnumerable <string> providerIds,
                                                                         ConcurrentDictionary <string, FundingPeriod> fundingPeriods)
        {
            LogInformation($"Merging specification information for specification {specificationInformation.Id} into summary for provider batch with length {providerIds.Count()}");

            foreach (string providerId in providerIds)
            {
                LogInformation($"Merging specification information for specification {specificationInformation.Id} into summary for provider {providerId}");

                ProviderWithResultsForSpecifications providerWithResultsForSpecifications = await GetProviderWithResultsByProviderId(providerId);

                providerWithResultsForSpecifications ??= new ProviderWithResultsForSpecifications
                {
                    Provider = new ProviderInformation
                    {
                        Id = providerId
                    }
                };

                await EnsureFundingPeriodEndDateQueried(specificationInformation, fundingPeriods);

                providerWithResultsForSpecifications.MergeSpecificationInformation(specificationInformation);

                if (providerWithResultsForSpecifications.GetIsDirty())
                {
                    await _results.UpsertSpecificationWithProviderResults(providerWithResultsForSpecifications);
                }
            }

            LogInformation($"Completed merging specification information for specification {specificationInformation.Id} into summary for provider batch with length {providerIds.Count()}");
        }
Beispiel #4
0
        private async Task EnsureFundingPeriodEndDateQueried(SpecificationInformation specificationInformation,
                                                             ConcurrentDictionary <string, FundingPeriod> fundingPeriods = null)
        {
            if (specificationInformation.FundingPeriodEnd.HasValue)
            {
                LogInformation($"Specification funding period end date for information for {specificationInformation.Id} already present.");
            }

            LogInformation($"Querying funding period end date for information for {specificationInformation.Id}");

            specificationInformation.FundingPeriodEnd = await GetFundingPeriodEndDate(specificationInformation.FundingPeriodId,
                                                                                      fundingPeriods);
        }
        public async Task MergeSpecificationInformationMergesForSpecificProviderIdsWhenSupplied()
        {
            string providerOneId = NewRandomString();
            string providerTwoId = NewRandomString();
            string jobId         = NewRandomString();

            string newFundingStreamIdOne = NewRandomString();
            string newFundingStreamIdTwo = NewRandomString();

            SpecificationInformation specificationInformation = NewSpecificationInformation(_ =>
                                                                                            _.WithFundingStreamIds(newFundingStreamIdOne, newFundingStreamIdTwo));
            MergeSpecificationInformationRequest mergeRequest = NewMergeSpecificationInformationRequest(_ => _.WithSpecificationInformation(specificationInformation)
                                                                                                        .WithProviderIds(providerOneId, providerTwoId));

            SpecificationInformation informationWithoutFundingStreams = specificationInformation.DeepCopy();

            informationWithoutFundingStreams.FundingStreamIds = null;

            ProviderWithResultsForSpecifications providerWithResultsForSpecificationsOne = NewProviderWithResultsForSpecifications(_ =>
                                                                                                                                   _.WithSpecifications(informationWithoutFundingStreams));
            ProviderWithResultsForSpecifications providerWithResultsForSpecificationsTwo = NewProviderWithResultsForSpecifications(_ =>
                                                                                                                                   _.WithSpecifications(informationWithoutFundingStreams));

            GivenTheProviderWithResultsForSpecificationsByProviderId(providerWithResultsForSpecificationsOne, providerOneId);
            GivenTheProviderWithResultsForSpecificationsByProviderId(providerWithResultsForSpecificationsTwo, providerTwoId);

            Message message = NewMessage(_ => _.WithUserProperty(JobId, jobId)
                                         .WithMessageBody(mergeRequest.AsJsonBytes()));

            await WhenTheSpecificationInformationIsMerged(message);

            ThenTheJobTrackingWasStarted(jobId);
            AndTheProviderWithResultsForSpecificationsWereUpserted(providerWithResultsForSpecificationsOne);
            AndTheProviderWithResultsForSpecificationsWereUpserted(providerWithResultsForSpecificationsTwo);

            specificationInformation.IsDirty = true;

            providerWithResultsForSpecificationsOne
            .Specifications
            .Should()
            .BeEquivalentTo(specificationInformation);

            providerWithResultsForSpecificationsTwo
            .Specifications
            .Should()
            .BeEquivalentTo(specificationInformation);

            AndTheJobTrackingWasCompleted(jobId);
        }
Beispiel #6
0
        private async Task MergeSpecificationInformationForAllProviders(SpecificationInformation specificationInformation)
        {
            string specificationId = specificationInformation.Id;

            LogInformation($"Merging specification information for specification {specificationId} into summary for all providers with results currently tracking it");

            ICosmosDbFeedIterator <ProviderWithResultsForSpecifications> providersWithResultsForSpecifications = GetProviderWithResultsBySpecificationId(specificationId);

            await EnsureFundingPeriodEndDateQueried(specificationInformation);

            MergeSpecificationInformationContext context = new MergeSpecificationInformationContext(providersWithResultsForSpecifications, specificationInformation);

            IProducerConsumer producerConsumer = _producerConsumerFactory.CreateProducerConsumer(ProduceProviderWithResultsForSpecifications,
                                                                                                 MergeSpecificationInformation,
                                                                                                 200,
                                                                                                 2,
                                                                                                 _logger);

            await producerConsumer.Run(context);
        }
Beispiel #7
0
        private async Task MergeSpecificationInformation(CancellationToken cancellationToken,
                                                         dynamic context,
                                                         IEnumerable <ProviderWithResultsForSpecifications> items)
        {
            SpecificationInformation specificationInformation = ((MergeSpecificationInformationContext)context).SpecificationInformation;

            LogInformation($"Merging SpecificationInformation for next {items.Count()} ProviderWithResultsForSpecifications");

            foreach (ProviderWithResultsForSpecifications providerWithResultsForSpecification in items)
            {
                providerWithResultsForSpecification.MergeSpecificationInformation(specificationInformation);

                LogInformation($"Merged specification information for {specificationInformation.Id} into ProviderWithResultsForSpecifications for provider {providerWithResultsForSpecification.Id}");
            }

            LogInformation($"Upserting page with {items.Count()} merged ProviderWithResultsForSpecifications for specification {specificationInformation.Id}");

            ProviderWithResultsForSpecifications[] dirtyItems = items.Where(_ => _.GetIsDirty()).ToArray();

            await _resultsPolicy.ExecuteAsync(() => _results.UpsertSpecificationWithProviderResults(dirtyItems));
        }
 public MergeSpecificationRequest(SpecificationInformation specificationInformation,
                                  string providerId)
 {
     SpecificationInformation = specificationInformation;
     ProviderId = providerId;
 }
Beispiel #9
0
 public MergeSpecificationInformationContext(ICosmosDbFeedIterator <ProviderWithResultsForSpecifications> feedIterator,
                                             SpecificationInformation specificationInformation)
 {
     FeedIterator             = feedIterator;
     SpecificationInformation = specificationInformation;
 }
Beispiel #10
0
        public MergeSpecificationInformationRequestBuilder WithSpecificationInformation(SpecificationInformation specificationInformation)
        {
            _specificationInformation = specificationInformation;

            return(this);
        }
 private Message NewMessage(SpecificationInformation specificationInformation,
                            params (string key, string value)[] properties)
 private void AndTheProviderWithResultsForSpecificationsHaveTheEquivalentSpecificationInformation(SpecificationInformation specificationInformation,
                                                                                                  params ProviderWithResultsForSpecifications[] providerWithResultsForSpecifications)
 {
     foreach (ProviderWithResultsForSpecifications providerWithResultsForSpecification in providerWithResultsForSpecifications)
     {
         providerWithResultsForSpecification
         .Specifications
         .Should()
         .BeEquivalentTo(new [] { specificationInformation },
                         opt => opt.Excluding(_ => _.IsDirty));
     }
 }
        public async Task MergeSpecificationInformationMergesForAllProviderWhenProviderIdNotSupplied()
        {
            string jobId           = NewRandomString();
            string specificationId = NewRandomString();

            SpecificationInformation             specificationInformation = NewSpecificationInformation(_ => _.WithId(specificationId));
            MergeSpecificationInformationRequest mergeRequest             = NewMergeSpecificationInformationRequest(_ => _.WithSpecificationInformation(specificationInformation));

            ProviderWithResultsForSpecifications providerOne   = NewProviderWithResultsForSpecifications();
            ProviderWithResultsForSpecifications providerTwo   = NewProviderWithResultsForSpecifications();
            ProviderWithResultsForSpecifications providerThree = NewProviderWithResultsForSpecifications();
            ProviderWithResultsForSpecifications providerFour  = NewProviderWithResultsForSpecifications();
            ProviderWithResultsForSpecifications providerFive  = NewProviderWithResultsForSpecifications();
            ProviderWithResultsForSpecifications providerSix   = NewProviderWithResultsForSpecifications();
            ProviderWithResultsForSpecifications providerSeven = NewProviderWithResultsForSpecifications();
            ProviderResult providerResultEight = NewProviderResult();
            ProviderWithResultsForSpecifications providerEight = NewProviderWithResultsForSpecifications(providerInformation: new ProviderInformation {
                Id = providerResultEight.Provider.Id
            });
            ProviderResult providerResultNine = NewProviderResult();
            ProviderWithResultsForSpecifications providerNine = NewProviderWithResultsForSpecifications(providerInformation: new ProviderInformation {
                Id = providerResultNine.Provider.Id
            });

            DateTimeOffset expectedFundingPeriodEndDate = NewRandomDateTime();

            GivenTheFundingPeriodEndDate(specificationInformation.FundingPeriodId, expectedFundingPeriodEndDate);
            AndTheProviderWithResultsForSpecifications(specificationId,
                                                       NewFeedIterator(AsArray(providerOne, providerTwo),
                                                                       AsArray(providerThree, providerFour),
                                                                       AsArray(providerFive, providerSix),
                                                                       AsArray(providerSeven, providerEight)));

            AndTheProviderResultsForSpecification(specificationId, new[] { providerResultEight, providerResultNine });

            Message message = NewMessage(_ => _.WithUserProperty(JobId, jobId)
                                         .WithMessageBody(mergeRequest.AsJsonBytes()));

            await WhenTheSpecificationInformationIsMerged(message);

            ThenTheJobTrackingWasStarted(jobId);

            SpecificationInformation expectedSpecificationInformation = specificationInformation.DeepCopy();

            expectedSpecificationInformation.FundingPeriodEnd = expectedFundingPeriodEndDate;

            AndTheProviderWithResultsForSpecificationsWereUpserted(providerOne,
                                                                   providerTwo);
            AndTheProviderWithResultsForSpecificationsWereUpserted(providerThree,
                                                                   providerFour);
            AndTheProviderWithResultsForSpecificationsWereUpserted(providerFive,
                                                                   providerSix);
            AndTheProviderWithResultsForSpecificationsWereUpserted(providerSeven,
                                                                   providerEight);

            //only upserts dirty records
            AndTheProviderWithResultsForSpecificationsWereNotUpserted(providerNine);

            expectedSpecificationInformation.IsDirty = true;

            AndTheProviderWithResultsForSpecificationsHaveTheEquivalentSpecificationInformation(expectedSpecificationInformation,
                                                                                                providerOne,
                                                                                                providerTwo,
                                                                                                providerThree,
                                                                                                providerFour,
                                                                                                providerFive,
                                                                                                providerSix,
                                                                                                providerSeven);

            AndTheJobTrackingWasCompleted(jobId);
        }