/// <summary> /// Registers a request with CNDS for distribution. /// </summary> /// <returns></returns> public async Task RegisterRequest(Dns.DTO.RequestDTO request, Guid networkID, Dns.Data.DataContext db) { var documents = await(from rd in db.RequestDocuments join doc in db.Documents on rd.RevisionSetID equals doc.RevisionSetID where rd.Response.RequestDataMart.RequestID == request.ID.Value && doc.ID == db.Documents.Where(dd => dd.RevisionSetID == rd.RevisionSetID).OrderByDescending(dd => dd.MajorVersion).ThenByDescending(dd => dd.MinorVersion).ThenByDescending(dd => dd.BuildVersion).ThenByDescending(dd => dd.RevisionVersion).Select(dd => dd.ID).FirstOrDefault() select new { SourceRequestDataSourceID = rd.Response.RequestDataMart.ID, ResponseID = rd.ResponseID, RevisionSetID = rd.RevisionSetID, DocumentID = doc.ID, Name = doc.Name, FileName = doc.FileName, IsViewable = doc.Viewable, Kind = doc.Kind, MimeType = doc.MimeType, Length = doc.Length, Description = doc.Description }).ToArrayAsync(); DTO.Requests.SubmitRequestDTO dto = new DTO.Requests.SubmitRequestDTO { SourceNetworkID = networkID, SourceRequestID = request.ID.Value, SerializedSourceRequest = Newtonsoft.Json.JsonConvert.SerializeObject(request), Documents = documents.Select(d => new DTO.Requests.SubmitRequestDocumentDetailsDTO { SourceRequestDataSourceID = d.SourceRequestDataSourceID, DocumentID = d.DocumentID, RevisionSetID = d.RevisionSetID, Description = d.Description, FileName = d.FileName, IsViewable = d.IsViewable, Kind = d.Kind, Length = d.Length, MimeType = d.MimeType, Name = d.Name }).ToArray() }; dto.Routes = (await(db.RequestDataMarts.Where(rdm => rdm.RequestID == dto.SourceRequestID) .Select(rdm => new { rdm.DataMartID, rdm.DueDate, rdm.Priority, rdm.ID, Responses = rdm.Responses.Select(rsp => new { rsp.ID, rsp.Count }) }).ToArrayAsync())) .Select(rdm => new DTO.Requests.SubmitRouteDTO { NetworkRouteDefinitionID = rdm.DataMartID, DueDate = rdm.DueDate, Priority = (int)rdm.Priority, SourceRequestDataMartID = rdm.ID, SourceResponseID = rdm.Responses.OrderByDescending(rsp => rsp.Count).Select(rsp => rsp.ID).FirstOrDefault(), RequestDocumentIDs = documents.Where(d => d.ResponseID == rdm.Responses.OrderByDescending(rsp => rsp.Count).Select(rsp => rsp.ID).First()).Select(d => d.DocumentID) }).ToArray(); await CNDSApi.Requests.Submit(dto); }
public async Task <HttpResponseMessage> Submit(DTO.Requests.SubmitRequestDTO dto) { //register the request with CNDS var request = DataContext.NetworkRequests.Add(new Data.Requests.NetworkRequest { ID = dto.SourceRequestID, NetworkID = dto.SourceNetworkID }); await DataContext.SaveChangesAsync(); var routeDefinitionIDs = dto.Routes.Select(rt => rt.NetworkRouteDefinitionID).ToArray(); var routeDefinitions = await DataContext.NetworkRequestTypeDefinitions.Where(rt => routeDefinitionIDs.Contains(rt.ID)).ToArrayAsync(); var networkIDs = (new[] { dto.SourceNetworkID }).Union(routeDefinitions.Select(rt => rt.NetworkID).Distinct()); var networkDetails = (await DataContext.Networks.Where(n => networkIDs.Contains(n.ID)).Select(n => new { n.ID, n.Name, n.ServiceUrl, n.ServiceUserName, n.ServicePassword }).ToArrayAsync()).ToDictionary(n => n.ID); var datasourceIDs = routeDefinitions.Select(rt => rt.DataSourceID).Distinct(); var dataSourceEntities = (await DataContext.NetworkEntities.Where(ne => datasourceIDs.Contains(ne.ID)).ToArrayAsync()).ToDictionary(ne => ne.ID); //TODO: make this an asynchronous parallel loop for the registering foreach (var participatingRoute in routeDefinitions.GroupBy(k => new { k.NetworkID, k.ProjectID, k.RequestTypeID })) { var participant = new Data.Requests.NetworkRequestParticipant { NetworkRequestID = request.ID, NetworkID = participatingRoute.Key.NetworkID, ProjectID = participatingRoute.Key.ProjectID, RequestTypeID = participatingRoute.Key.RequestTypeID }; request.Participants.Add(participant); var requestDocuments = dto.Documents.Select(d => { Guid docID = DatabaseEx.NewGuid(); return(new { SourceDocumentID = d.DocumentID, SourceRequestDataMartID = d.SourceRequestDataSourceID, DTO = new Dns.DTO.CNDSRegisterDocumentDTO { SourceDocumentID = d.DocumentID, SourceRevisionSetID = d.RevisionSetID, DocumentID = docID, RevisionSetID = docID, Name = d.Name, FileName = d.FileName, Kind = d.Kind, MimeType = d.MimeType, Length = d.Length, IsViewable = d.IsViewable, Description = d.Description } }); }).ToArray(); var network = networkDetails[participatingRoute.Key.NetworkID]; using (var pmnAPI = new Dns.ApiClient.DnsClient(network.ServiceUrl, network.ServiceUserName, Lpp.Utilities.Crypto.DecryptString(network.ServicePassword))) { var requestDto = new Dns.DTO.CNDSRegisterRequestDTO { ParticipantID = participant.ID, ProjectID = participatingRoute.Key.ProjectID, RequestTypeID = participatingRoute.Key.RequestTypeID, SourceNetworkID = request.NetworkID, SourceNetworkName = networkDetails[request.NetworkID].Name, RequestDetails = dto.SerializedSourceRequest, Documents = requestDocuments.Select(d => d.DTO).ToArray() }; HashSet <Dns.DTO.CNDSRegisterRouteDTO> routeDTOs = new HashSet <Dns.DTO.CNDSRegisterRouteDTO>(); foreach (var rt in participatingRoute) { var rtDTO = dto.Routes.First(x => x.NetworkRouteDefinitionID == rt.ID); var route = new Data.Requests.NetworkRequestRoute { DataSourceID = rt.DataSourceID, ParticipantID = participant.ID, SourceRequestDataMartID = rtDTO.SourceRequestDataMartID }; var response = new Data.Requests.NetworkRequestResponse { IterationIndex = 1, NetworkRequestRouteID = route.ID, SourceResponseID = rtDTO.SourceResponseID }; var responseDocuments = new HashSet <Data.Requests.NetworkRequestDocument>(); foreach (var requestDocument in requestDocuments.Where(rd => rtDTO.RequestDocumentIDs.Contains(rd.SourceDocumentID) && rd.SourceRequestDataMartID == route.SourceRequestDataMartID)) { responseDocuments.Add(new Data.Requests.NetworkRequestDocument { //the ID of the request document in CNDS will be the ID of the document in the destination network ID = requestDocument.DTO.DocumentID, DestinationRevisionSetID = requestDocument.DTO.RevisionSetID, ResponseID = response.ID, SourceDocumentID = requestDocument.SourceDocumentID }); } response.Documents = responseDocuments; route.Responses.Add(response); participant.Routes.Add(route); routeDTOs.Add(new Dns.DTO.CNDSRegisterRouteDTO { RouteID = route.ID, //Specify the destination networks DataMart ID, not the CNDS DataSource ID DataMartID = dataSourceEntities[rt.DataSourceID].NetworkEntityID, DueDate = rtDTO.DueDate, Priority = (Dns.DTO.Enums.Priorities)rtDTO.Priority, ResponseID = response.ID, //The ID will be the ID of the document in the destination network DocumentIDs = response.Documents.Select(d => d.ID).ToArray() }); } requestDto.Routes = routeDTOs; try { await DataContext.SaveChangesAsync(); } catch (Exception ex) { Logger.Error(ex.Message, ex); return(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex)); } //has to be saved prior to registering in the participating network to allow for the documents to exist when the participant tries to get the document content. var resp = await pmnAPI.CNDSRequests.Register(requestDto); if (!resp.IsSuccessStatusCode) { return(Request.CreateErrorResponse(resp.StatusCode, resp.ReasonPhrase)); } } } return(Request.CreateResponse(HttpStatusCode.OK)); }