private async Task <IEnumerable <TemplateMappingItem> > GetTemplateMappingItemsInSpecification(SpecificationSummary specification, MigrationClients clients) { SemaphoreSlim throttle = new SemaphoreSlim(5, 5); ConcurrentBag <Task <TemplateMapping> > templateMappingQueryTasks = new ConcurrentBag <Task <TemplateMapping> >(); string specificationId = specification.Id; foreach (Reference fundingStream in specification.FundingStreams) { templateMappingQueryTasks.Add(Task.Run(() => { try { throttle.Wait(); string fundingStreamId = fundingStream.Id; ApiResponse <TemplateMapping> templateMappingResponse = clients.MakeCalculationsCall(_ => _.GetTemplateMapping(specificationId, fundingStreamId)) .GetAwaiter() .GetResult(); CheckApiResponse(templateMappingResponse, $"Unable to fetch template mapping for specification id {specificationId} and funding stream id {fundingStreamId}"); return(templateMappingResponse.Content); } finally { throttle.Release(); } })); } await TaskHelper.WhenAllAndThrow(templateMappingQueryTasks.ToArray()); return(templateMappingQueryTasks.SelectMany(_ => _.Result.TemplateMappingItems).ToArray()); }
private async Task <bool> TryMigrateCalculations(SpecificationSummary sourceSpecification, SpecificationSummary destinationSpecification) { /* * Create any missing additional calculations on destination specification * Get the template calculation mapping for source and destination specifications for each funding streams * Set the source code in the destination calculation for each of the calculations (based on TemplateCalculationId) where the source code is different */ string sourceSpecificationId = sourceSpecification.Id; string destinationSpecificationId = destinationSpecification.Id; Task <IEnumerable <TemplateMappingItem> > sourceTemplateMappingsQueryTask = GetTemplateMappingItemsInSpecification(sourceSpecification, _sourceClients); Task <IEnumerable <TemplateMappingItem> > destinationTemplateMappingsQueryTask = GetTemplateMappingItemsInSpecification(destinationSpecification, _destinationClients); Task <ApiResponse <IEnumerable <Calculation> > > sourceCalculationsQueryTask = _sourceClients.MakeCalculationsCall( _ => _.GetCalculationsForSpecification(sourceSpecificationId)); Task <ApiResponse <IEnumerable <Calculation> > > destinationCalculationsQueryTask = _destinationClients.MakeCalculationsCall( _ => _.GetCalculationsForSpecification(destinationSpecificationId)); WriteLine("Fetching template mappings and current calculation versions from source and destination specifications"); await TaskHelper.WhenAllAndThrow(sourceCalculationsQueryTask, destinationCalculationsQueryTask, sourceTemplateMappingsQueryTask, destinationTemplateMappingsQueryTask); ApiResponse <IEnumerable <Calculation> > sourceCalculationsResponse = sourceCalculationsQueryTask.Result; ApiResponse <IEnumerable <Calculation> > destinationCalculationsResponse = destinationCalculationsQueryTask.Result; CheckApiResponse(sourceCalculationsResponse, $"Unable to query current calculations for source specification {sourceSpecificationId}"); CheckApiResponse(destinationCalculationsResponse, $"Unable to query current calculations for destination specification {destinationSpecificationId}"); CalculationType additional = CalculationType.Additional; Calculation[] sourceAdditionalCalculations = sourceCalculationsResponse.Content.Where( _ => _.CalculationType == additional).ToArray(); Calculation[] destinationAdditionalCalculations = destinationCalculationsResponse.Content.Where( _ => _.CalculationType == additional).ToArray(); var template = CalculationType.Template; Dictionary <string, Calculation> sourceTemplateCalculations = sourceCalculationsResponse.Content.Where( _ => _.CalculationType == template).ToDictionary(_ => _.Id, _ => _); Dictionary <string, Calculation> destinationTemplateCalculations = destinationCalculationsResponse.Content.Where( _ => _.CalculationType == template).ToDictionary(_ => _.Id, _ => _); TemplateMappingItem[] sourceTemplateMappings = sourceTemplateMappingsQueryTask.Result.Where( _ => _.EntityType == TemplateMappingEntityType.Calculation) .ToArray(); Dictionary <uint, string> destinationTemplateIdToCalculationIdMappings = destinationTemplateMappingsQueryTask .Result.Where(_ => _.EntityType == TemplateMappingEntityType.Calculation) .ToDictionary(_ => _.TemplateId, _ => _.CalculationId); CheckForTemplateErrors(sourceTemplateMappings, destinationTemplateIdToCalculationIdMappings); if (MigrationHasErrors) { return(false); } WriteLine("Creating missing additional calculations from source specification in destination specification"); await CreateMissingAdditionalCalculations(sourceAdditionalCalculations, destinationAdditionalCalculations, destinationSpecificationId); if (MigrationHasErrors) { return(false); } WriteLine("Updating source code for any template calculations in destination specification where this differs in source (using template id to match calculations)"); await EnsureDestinationTemplateCalculationSourceCodeMatchesSource(sourceTemplateMappings, destinationTemplateIdToCalculationIdMappings, sourceTemplateCalculations, destinationTemplateCalculations, destinationSpecificationId); return(!MigrationHasErrors); }