/// <summary> /// Get one registration event /// </summary> public Core.ComponentModel.RegistrationEvent GetRegistrationEvent(decimal id) { // Get all Services IAuditorService auditSvc = ApplicationContext.CurrentContext.GetService(typeof(IAuditorService)) as IAuditorService; IDataPersistenceService repSvc = ApplicationContext.CurrentContext.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService; // Audit message AuditData audit = this.ConstructAuditData(ActionType.Read, EventIdentifierType.Export); audit.EventTypeCode = new CodeValue("ADM_GetRegistrationEvent"); try { // Result identifiers var retVal = repSvc.GetContainer(new VersionedDomainIdentifier() { Domain = ApplicationContext.ConfigurationService.OidRegistrar.GetOid("REG_EVT").Oid, Identifier = id.ToString() }, false) as RegistrationEvent; // Add audit data if (retVal != null) { audit.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.ReportNumber, LifecycleType = AuditableObjectLifecycle.Export, ObjectId = String.Format("{0}^^^&{1}&ISO", retVal.AlternateIdentifier.Identifier, retVal.AlternateIdentifier.Domain), Role = AuditableObjectRole.MasterFile, Type = AuditableObjectType.SystemObject, QueryData = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("loadFast=false")) }); } return(retVal); } catch (Exception e) { Trace.TraceError("Could not execute GetRegistration : {0}", e.ToString()); audit.Outcome = OutcomeIndicator.EpicFail; #if DEBUG throw new FaultException(new FaultReason(e.ToString()), new FaultCode(e.GetType().Name)); #else throw new FaultException(new FaultReason(e.Message), new FaultCode(e.GetType().Name)); #endif } finally { if (auditSvc != null) { auditSvc.SendAudit(audit); } } }
/// <summary> /// Delete a resource /// </summary> public DomainResourceBase DeleteResource(string resourceType, string id, string mimeType) { this.ThrowIfNotReady(); FhirOperationResult result = null; AuditData audit = null; IAuditorService auditService = ApplicationContext.Current.GetService(typeof(IAuditorService)) as IAuditorService; try { // Setup outgoing content/ WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NoContent; // Create or update? var handler = FhirResourceHandlerUtil.GetResourceHandler(resourceType); if (handler == null) { throw new FileNotFoundException(); // endpoint not found! } result = handler.Delete(id, TransactionMode.Commit); if (result == null || result.Outcome == ResultCode.Rejected) { throw new NotSupportedException(); } else if (result.Outcome == ResultCode.TypeNotAvailable) { throw new FileNotFoundException(String.Format("Resource {0} not found", WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri)); } else if (result.Outcome != ResultCode.Accepted) { throw new DataException("Delete failed"); } audit = AuditUtil.CreateAuditData(result.Results); return(null); } catch (Exception e) { audit = AuditUtil.CreateAuditData(null); audit.Outcome = OutcomeIndicator.EpicFail; return(this.ErrorHelper(e, result, false) as DomainResourceBase); } finally { if (auditService != null) { auditService.SendAudit(audit); } } }
/// <summary> /// Resolve an item /// </summary> /// <param name="sourceId"></param> public void Resolve(decimal sourceId) { // Get all Services IAuditorService auditSvc = ApplicationContext.CurrentContext.GetService(typeof(IAuditorService)) as IAuditorService; IClientRegistryMergeService mergeSvc = ApplicationContext.CurrentContext.GetService(typeof(IClientRegistryMergeService)) as IClientRegistryMergeService; // Audit message AuditData auditMessage = this.ConstructAuditData(ActionType.Update, EventIdentifierType.ApplicationActivity); auditMessage.EventTypeCode = new CodeValue("ADM_Resolve"); try { // Prepare merge VersionedDomainIdentifier resolveId = new VersionedDomainIdentifier() { Domain = ApplicationContext.ConfigurationService.OidRegistrar.GetOid("REG_EVT").Oid, Identifier = sourceId.ToString() }; // Merge mergeSvc.MarkResolved(resolveId); auditMessage.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.ReportNumber, LifecycleType = AuditableObjectLifecycle.Verification, ObjectId = string.Format("{0}^^^&{1}&ISO", resolveId.Identifier, resolveId.Domain), Role = AuditableObjectRole.Job, Type = AuditableObjectType.SystemObject }); } catch (Exception e) { auditMessage.Outcome = OutcomeIndicator.EpicFail; Trace.TraceError("Could not execute Merge : {0}", e.ToString()); #if DEBUG throw new FaultException(new FaultReason(e.ToString()), new FaultCode(e.GetType().Name)); #else throw new FaultException(new FaultReason(e.Message), new FaultCode(e.GetType().Name)); #endif } finally { if (auditSvc != null) { auditSvc.SendAudit(auditMessage); } } }
/// <summary> /// Patient registry get identifiers query /// </summary> /// <param name="e"></param> /// <param name="receivedMessage"></param> /// <returns></returns> private IGraphable PatientRegistryGetIdentifiers(UnsolicitedDataEventArgs e, IReceiveResult receivedMessage) { // Setup the lists of details and issues List <IResultDetail> dtls = new List <IResultDetail>(receivedMessage.Details); // System configuration service ISystemConfigurationService configService = Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; // Localization service ILocalizationService locale = Context.GetService(typeof(ILocalizationService)) as ILocalizationService; // Data Service IClientRegistryDataService dataSvc = Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService; // Do basic check and add common validation errors MessageUtil.ValidateTransportWrapperUv(receivedMessage.Structure as IInteraction, configService, dtls); // Check the request is valid var request = receivedMessage.Structure as PRPA_IN201309UV02; if (request == null) { return(null); } // Determine if the received message was interpreted properly bool isValid = MessageUtil.IsValid(receivedMessage); // set the URI if (request.controlActProcess != null) { request.controlActProcess.Code = request.controlActProcess.Code ?? Util.Convert <CD <String> >(PRPA_IN201302UV02.GetTriggerEvent()); } if (request.Receiver.Count > 0) { request.Receiver[0].Telecom = request.Receiver[0].Telecom ?? e.ReceiveEndpoint.ToString(); } // Construct the acknowledgment var response = new PRPA_IN201310UV02( new II(configService.OidRegistrar.GetOid("CR_MSGID").Oid, Guid.NewGuid().ToString()), DateTime.Now, PRPA_IN201310UV02.GetInteractionId(), request.ProcessingCode, request.ProcessingModeCode, AcknowledgementCondition.Never, MessageUtil.CreateReceiver(request.Sender), MessageUtil.CreateSenderUv(e.ReceiveEndpoint, configService), null ); // Create the support classes AuditData audit = null; IheAuditUtil dataUtil = new IheAuditUtil() { Context = this.Context }; // Try to execute the record try { // Determine if the message is valid if (!isValid) { throw new MessageValidationException(locale.GetString("MSGE00A"), receivedMessage.Structure); } // Construct the canonical data structure GetIdentifiersQueryResponseFactory fact = new GetIdentifiersQueryResponseFactory() { Context = this.Context }; RegistryQueryRequest filter = fact.CreateFilterData(request, dtls); if (filter.QueryRequest == null) { throw new MessageValidationException(locale.GetString("MSGE00A"), receivedMessage.Structure); } // Query var results = dataSvc.Query(filter); dtls.AddRange(results.Details); // Prepare for audit audit = dataUtil.CreateAuditData("ITI-45", ActionType.Execute, dtls.Exists(r => r.Type == ResultDetailType.Error) ? OutcomeIndicator.MinorFail : OutcomeIndicator.Success, e, receivedMessage, results, filter.QueryRequest.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.AuthorOf) as HealthcareParticipant ); response = fact.Create(request, results, dtls) as PRPA_IN201310UV02; } catch (Exception ex) { Trace.TraceError(ex.ToString()); // Prepare for audit audit = dataUtil.CreateAuditData("ITI-45", ActionType.Execute, OutcomeIndicator.EpicFail, e, receivedMessage, new List <VersionedDomainIdentifier>(), null ); dtls.Add(new ResultDetail(ResultDetailType.Error, ex.Message, ex)); response.Acknowledgement.Add(new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100300UV01.Acknowledgement( AcknowledgementType.AcceptAcknowledgementCommitError, new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100200UV01.TargetMessage(request.Id) )); } finally { IAuditorService auditService = Context.GetService(typeof(IAuditorService)) as IAuditorService; if (auditService != null) { auditService.SendAudit(audit); } } // Common response parameters response.ProfileId = new SET <II>(MCCI_IN000002UV01.GetProfileId()); response.VersionCode = HL7StandardVersionCode.Version3_Prerelease1; response.AcceptAckCode = AcknowledgementCondition.Never; response.Acknowledgement[0].AcknowledgementDetail.AddRange(MessageUtil.CreateAckDetailsUv(dtls.ToArray())); return(response); }
/// <summary> /// Handle duplicates resolved message /// </summary> private IGraphable HandlePatientRegistryDuplicatesResolved(MARC.Everest.Connectors.UnsolicitedDataEventArgs e, MARC.Everest.Connectors.IReceiveResult receivedMessage) { // Setup the lists of details and issues List <IResultDetail> dtls = new List <IResultDetail>(receivedMessage.Details); // System configuration service ISystemConfigurationService configService = Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; // Localization service ILocalizationService locale = Context.GetService(typeof(ILocalizationService)) as ILocalizationService; // Data Service IClientRegistryDataService dataSvc = Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService; // Do basic check and add common validation errors MessageUtil.ValidateTransportWrapperUv(receivedMessage.Structure as IInteraction, configService, dtls); // Check the request is valid var request = receivedMessage.Structure as PRPA_IN201304UV02; if (request == null) { return(null); } // Determine if the received message was interpreted properly bool isValid = MessageUtil.IsValid(receivedMessage); // set the URI if (request.controlActProcess != null) { request.controlActProcess.Code = request.controlActProcess.Code ?? Util.Convert <CD <String> >(PRPA_IN201302UV02.GetTriggerEvent()); } if (request.Receiver.Count > 0) { request.Receiver[0].Telecom = request.Receiver[0].Telecom ?? e.ReceiveEndpoint.ToString(); } // Construct the acknowledgment var response = new MCCI_IN000002UV01( new II(configService.OidRegistrar.GetOid("CR_MSGID").Oid, Guid.NewGuid().ToString()), DateTime.Now, MCCI_IN000002UV01.GetInteractionId(), request.ProcessingCode, request.ProcessingModeCode, MessageUtil.CreateReceiver(request.Sender), MessageUtil.CreateSenderUv(e.ReceiveEndpoint, configService) ); // Create the support classes List <AuditData> audits = new List <AuditData>(); IheAuditUtil dataUtil = new IheAuditUtil() { Context = this.Context }; // Try to execute the record try { // Determine if the message is valid if (!isValid) { throw new MessageValidationException(locale.GetString("MSGE00A"), receivedMessage.Structure); } // Construct the canonical data structure UvComponentUtil cu = new UvComponentUtil() { Context = this.Context }; RegistrationEvent data = cu.CreateComponents(request.controlActProcess, dtls); // Componentization fail? if (data == null || !dataUtil.ValidateIdentifiers(data, dtls)) { throw new MessageValidationException(locale.GetString("MSGE00A"), receivedMessage.Structure); } // Store var result = dataSvc.Merge(data, request.ProcessingCode != ProcessingID.Production ? DataPersistenceMode.Debugging : DataPersistenceMode.Production); if (result == null || result.VersionId == null) { throw new Exception(locale.GetString("DTPE001")); } dtls.AddRange(result.Details); // prepare the delete audit var person = data.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person; var replc = person.FindAllComponents(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.ReplacementOf); foreach (PersonRegistrationRef rplc in replc) { audits.Add(dataUtil.CreateAuditData("ITI-44", ActionType.Delete, dtls.Exists(r => r.Type == ResultDetailType.Error) ? OutcomeIndicator.MinorFail : OutcomeIndicator.Success, e, receivedMessage, new List <VersionedDomainIdentifier>() { new VersionedDomainIdentifier() { Domain = rplc.AlternateIdentifiers[0].Domain, Identifier = rplc.AlternateIdentifiers[0].Identifier } }, data.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.AuthorOf) as HealthcareParticipant)); } // Prepare for audit audits.Add(dataUtil.CreateAuditData("ITI-44", ActionType.Update, dtls.Exists(r => r.Type == ResultDetailType.Error) ? OutcomeIndicator.MinorFail : OutcomeIndicator.Success, e, receivedMessage, new List <VersionedDomainIdentifier>() { result.VersionId }, data.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.AuthorOf) as HealthcareParticipant )); // Add ack response.Acknowledgement.Add(new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100200UV01.Acknowledgement( AcknowledgementType.AcceptAcknowledgementCommitAccept, new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100200UV01.TargetMessage(request.Id) )); } catch (Exception ex) { Trace.TraceError(ex.ToString()); // Prepare for audit audits.Add(dataUtil.CreateAuditData("ITI-44", ActionType.Create, OutcomeIndicator.EpicFail, e, receivedMessage, new List <VersionedDomainIdentifier>(), null )); dtls.Add(new ResultDetail(ResultDetailType.Error, ex.Message, ex)); response.Acknowledgement.Add(new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100200UV01.Acknowledgement( AcknowledgementType.AcceptAcknowledgementCommitError, new MARC.Everest.RMIM.UV.NE2008.MCCI_MT100200UV01.TargetMessage(request.Id) )); } finally { IAuditorService auditService = Context.GetService(typeof(IAuditorService)) as IAuditorService; if (auditService != null) { foreach (var aud in audits) { auditService.SendAudit(aud); } } } // Common response parameters response.ProfileId = new SET <II>(MCCI_IN000002UV01.GetProfileId()); response.VersionCode = HL7StandardVersionCode.Version3_Prerelease1; response.AcceptAckCode = AcknowledgementCondition.Never; response.Acknowledgement[0].AcknowledgementDetail.AddRange(MessageUtil.CreateAckDetailsUv(dtls.ToArray())); return(response); }
/// <summary> /// Create a resource /// </summary> public DomainResourceBase CreateResource(string resourceType, string mimeType, DomainResourceBase target) { this.ThrowIfNotReady(); FhirOperationResult result = null; AuditData audit = null; IAuditorService auditService = ApplicationContext.Current.GetService(typeof(IAuditorService)) as IAuditorService; try { // Setup outgoing content // Create or update? var handler = FhirResourceHandlerUtil.GetResourceHandler(resourceType); if (handler == null) { throw new FileNotFoundException(); // endpoint not found! } result = handler.Create(target, TransactionMode.Commit); WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Created; if (result == null || result.Outcome == ResultCode.Rejected) { throw new InvalidDataException("Resource structure is not valid"); } else if (result.Outcome == ResultCode.AcceptedNonConformant) { throw new ConstraintException("Resource not conformant"); } else if (result.Outcome == ResultCode.TypeNotAvailable) { throw new FileNotFoundException(String.Format("Resource {0} not found", WebOperationContext.Current.IncomingRequest.UriTemplateMatch.RequestUri)); } else if (result.Outcome != ResultCode.Accepted) { throw new DataException("Create failed"); } audit = AuditUtil.CreateAuditData(result.Results); String baseUri = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri.AbsoluteUri; WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Location", String.Format("{0}{1}/{2}/_history/{3}", baseUri, resourceType, result.Results[0].Id, result.Results[0].VersionId)); WebOperationContext.Current.OutgoingResponse.LastModified = result.Results[0].Timestamp; WebOperationContext.Current.OutgoingResponse.ETag = result.Results[0].VersionId; return(result.Results[0]); } catch (Exception e) { audit = AuditUtil.CreateAuditData(null); audit.Outcome = OutcomeIndicator.EpicFail; return(this.ErrorHelper(e, result, false) as DomainResourceBase); } finally { if (auditService != null) { auditService.SendAudit(audit); } } }
/// <summary> /// Handles a received message /// </summary> public MARC.Everest.Interfaces.IGraphable HandleMessageReceived(object sender, UnsolicitedDataEventArgs e, MARC.Everest.Connectors.IReceiveResult receivedMessage) { // audit the error IAuditorService auditor = Context.GetService(typeof(IAuditorService)) as IAuditorService; AuditData ad = new AuditData( DateTime.Now, ActionType.Execute, OutcomeIndicator.EpicFail, EventIdentifierType.ApplicationActivity, new CodeValue(String.Format("{0}", receivedMessage.Structure)) ); ad.Actors.AddRange(new List <AuditActorData>(10) { new AuditActorData() { NetworkAccessPointId = e.ReceiveEndpoint.ToString(), NetworkAccessPointType = NetworkAccessPointType.IPAddress, UserIsRequestor = false }, new AuditActorData() { NetworkAccessPointType = NetworkAccessPointType.MachineName, NetworkAccessPointId = Environment.MachineName, UserIsRequestor = false } } ); ad.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.ReportNumber, LifecycleType = AuditableObjectLifecycle.Verification, ObjectId = (receivedMessage.Structure as IIdentifiable).Id.Root, Role = AuditableObjectRole.Subscriber, Type = AuditableObjectType.SystemObject }); if (auditor != null) { auditor.SendAudit(ad); } IInteraction solicitation = receivedMessage.Structure as IInteraction; // get the configuration ISystemConfigurationService configService = Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; // construct a generic response MCCI_IN000002CA response = new MCCI_IN000002CA( Guid.NewGuid(), DateTime.Now, new CV <ResponseMode>(ResponseMode.Immediate), MCCI_IN000002CA.GetInteractionId(), MCCI_IN000002CA.GetProfileId(), ProcessingID.Debugging, AcknowledgementCondition.Never, null, MessageUtil.CreateSender(e.ReceiveEndpoint, configService), new Acknowledgement( AcknowledgementType.ApplicationAcknowledgementReject, new TargetMessage( (receivedMessage.Structure as IIdentifiable).Id ) ) ); // Add a detail if (solicitation.InteractionId != null && solicitation.InteractionId.Extension != receivedMessage.Structure.GetType().Name) { response.Acknowledgement.AcknowledgementDetail.Add( new AcknowledgementDetail( AcknowledgementDetailType.Error, Util.ToWireFormat(MARC.Everest.RMIM.CA.R020402.Vocabulary.AcknowledgementDetailCode.ValueDoesNotMatchFixedValue), String.Format("Interaction ID '{0}' not supported for message type '{1}'", solicitation.InteractionId.Extension, receivedMessage.Structure.GetType().Name), null)); } else { response.Acknowledgement.AcknowledgementDetail.Add( new AcknowledgementDetail( AcknowledgementDetailType.Error, Util.ToWireFormat(MARC.Everest.RMIM.CA.R020402.Vocabulary.AcknowledgementDetailCode.UnsupportedInteraction), "Cannot process this interaction", null) ); } // Validation detils response.Acknowledgement.AcknowledgementDetail.AddRange(MessageUtil.CreateGenAckDetails(receivedMessage.Details)); // Populate the receiver Sender originalSolicitor = solicitation.GetType().GetProperty("Sender").GetValue(solicitation, null) as Sender; Receiver receiver = MessageUtil.CreateReceiver(originalSolicitor); response.Receiver = receiver; return(response); }
/// <summary> /// Get recent activity /// </summary> public RegistrationEventCollection GetRecentActivity(TimestampSet timeRange, int offset, int count, bool identifierOnly) { // Get all Services IAuditorService auditSvc = ApplicationContext.CurrentContext.GetService(typeof(IAuditorService)) as IAuditorService; IDataRegistrationService regSvc = ApplicationContext.CurrentContext.GetService(typeof(IDataRegistrationService)) as IDataRegistrationService; IDataPersistenceService repSvc = ApplicationContext.CurrentContext.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService; // Audit message AuditData audit = this.ConstructAuditData(ActionType.Read, EventIdentifierType.Export); audit.EventTypeCode = new CodeValue("ADM_GetRegistrations"); try { // Result identifiers VersionedDomainIdentifier[] vids = null; var dummyQuery = new QueryEvent(); dummyQuery.Add(new RegistrationEvent() { EventClassifier = RegistrationEventType.Register, EffectiveTime = timeRange }, "SUBJ", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf, null); vids = regSvc.QueryRecord(dummyQuery); RegistrationEventCollection retVal = new RegistrationEventCollection(); Object syncLock = new object(); retVal.Count = vids.Length; // Now fetch each one asynchronously if (!identifierOnly) { using (WaitThreadPool thdPool = new WaitThreadPool(Environment.ProcessorCount * 2)) { foreach (var id in vids.Skip(offset).Take(count)) { thdPool.QueueUserWorkItem( delegate(object state) { try { var itm = repSvc.GetContainer(state as VersionedDomainIdentifier, true); lock (syncLock) retVal.Event.Add(itm as RegistrationEvent); } catch (Exception e) { Trace.TraceError("Could not fetch result {0} : {1}", (state as VersionedDomainIdentifier).Identifier, e.ToString()); } } , id); } // Wait until fetch is done thdPool.WaitOne(new TimeSpan(0, 0, 30), false); } //retVal.Event.Sort((a, b) => b.Timestamp.CompareTo(a.Timestamp)); // Add audit data foreach (var res in retVal.Event) { audit.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.ReportNumber, LifecycleType = AuditableObjectLifecycle.Export, ObjectId = String.Format("{0}^^^&{1}&ISO", res.AlternateIdentifier.Identifier, res.AlternateIdentifier.Domain), Role = AuditableObjectRole.MasterFile, Type = AuditableObjectType.SystemObject, QueryData = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("loadFast=true")) }); } } return(retVal); } catch (Exception e) { Trace.TraceError("Could not execute GetRegistrations : {0}", e.ToString()); audit.Outcome = OutcomeIndicator.EpicFail; #if DEBUG throw new FaultException(new FaultReason(e.ToString()), new FaultCode(e.GetType().Name)); #else throw new FaultException(new FaultReason(e.Message), new FaultCode(e.GetType().Name)); #endif } finally { if (auditSvc != null) { auditSvc.SendAudit(audit); } } }
/// <summary> /// Perform a merge /// </summary> public Core.ComponentModel.RegistrationEvent Merge(decimal[] sourceIds, decimal targetId) { // Get all Services IAuditorService auditSvc = ApplicationContext.CurrentContext.GetService(typeof(IAuditorService)) as IAuditorService; IDataPersistenceService repSvc = ApplicationContext.CurrentContext.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService; IClientRegistryMergeService mergeSvc = ApplicationContext.CurrentContext.GetService(typeof(IClientRegistryMergeService)) as IClientRegistryMergeService; // Audit message List <AuditData> auditMessages = new List <AuditData>(); try { // Prepare merge List <VersionedDomainIdentifier> domainId = new List <VersionedDomainIdentifier>(sourceIds.Length); foreach (var srcId in sourceIds) { domainId.Add(new VersionedDomainIdentifier() { Domain = ApplicationContext.ConfigurationService.OidRegistrar.GetOid("REG_EVT").Oid, Identifier = srcId.ToString() }); var am = ConstructAuditData(ActionType.Delete, EventIdentifierType.Import); am.EventTypeCode = new CodeValue("ADM_Merge"); am.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.ReportNumber, LifecycleType = AuditableObjectLifecycle.LogicalDeletion, ObjectId = String.Format("{0}^^^&{1}&ISO", srcId, ApplicationContext.ConfigurationService.OidRegistrar.GetOid("REG_EVT").Oid), Role = AuditableObjectRole.MasterFile, Type = AuditableObjectType.SystemObject }); auditMessages.Add(am); } VersionedDomainIdentifier survivorId = new VersionedDomainIdentifier() { Domain = ApplicationContext.ConfigurationService.OidRegistrar.GetOid("REG_EVT").Oid, Identifier = targetId.ToString() }; var updateAudit = ConstructAuditData(ActionType.Update, EventIdentifierType.Import); updateAudit.EventTypeCode = new CodeValue("ADM_Merge"); updateAudit.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.ReportNumber, LifecycleType = AuditableObjectLifecycle.Amendment, ObjectId = String.Format("{0}^^^&{1}&ISO", survivorId.Identifier, survivorId.Domain), Role = AuditableObjectRole.MasterFile, Type = AuditableObjectType.SystemObject }); auditMessages.Add(updateAudit); // Merge mergeSvc.Resolve(domainId, survivorId, DataPersistenceMode.Production); // Now load return(repSvc.GetContainer(survivorId, true) as RegistrationEvent); } catch (Exception e) { foreach (var am in auditMessages) { am.Outcome = OutcomeIndicator.EpicFail; } Trace.TraceError("Could not execute Merge : {0}", e.ToString()); #if DEBUG throw new FaultException(new FaultReason(e.ToString()), new FaultCode(e.GetType().Name)); #else throw new FaultException(new FaultReason(e.Message), new FaultCode(e.GetType().Name)); #endif } finally { if (auditSvc != null) { foreach (var am in auditMessages) { auditSvc.SendAudit(am); } } } }
/// <summary> /// Get all merge candidates /// </summary> public ConflictCollection GetConflicts(int offset, int count, bool identifierOnly) { // Get all Services IAuditorService auditSvc = ApplicationContext.CurrentContext.GetService(typeof(IAuditorService)) as IAuditorService; IDataPersistenceService repSvc = ApplicationContext.CurrentContext.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService; IClientRegistryMergeService mergeSvc = ApplicationContext.CurrentContext.GetService(typeof(IClientRegistryMergeService)) as IClientRegistryMergeService; // Audit message AuditData audit = this.ConstructAuditData(ActionType.Read, EventIdentifierType.Export); audit.EventTypeCode = new CodeValue("ADM_GetConflicts"); try { // Get all with a merge var mergeResults = mergeSvc.GetOutstandingConflicts(); var retVal = new ConflictCollection(); retVal.Count = mergeResults.Count(); // Loop and load foreach (var merge in mergeResults.Skip(offset).Take(count)) { // Construct the return, and load match Conflict conf = new Conflict(); if (!identifierOnly) { conf.Source = repSvc.GetContainer(merge, true) as RegistrationEvent; // Add audit data audit.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.ReportNumber, LifecycleType = AuditableObjectLifecycle.Export, ObjectId = String.Format("{0}^^^&{1}&ISO", conf.Source.AlternateIdentifier.Identifier, conf.Source.AlternateIdentifier.Domain), Role = AuditableObjectRole.MasterFile, Type = AuditableObjectType.SystemObject, QueryData = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("loadFast=false")) }); } // Load the matches foreach (var match in mergeSvc.GetConflicts(merge)) { if (!identifierOnly) { var matchRecord = repSvc.GetContainer(match, true) as RegistrationEvent; conf.Match.Add(matchRecord); // Add audit data audit.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.ReportNumber, LifecycleType = AuditableObjectLifecycle.Export, ObjectId = String.Format("{0}^^^&{1}&ISO", matchRecord.AlternateIdentifier.Identifier, matchRecord.AlternateIdentifier.Domain), Role = AuditableObjectRole.MasterFile, Type = AuditableObjectType.SystemObject, QueryData = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("loadFast=false")) }); } else { conf.Match.Add(new RegistrationEvent() { AlternateIdentifier = match }); } } retVal.Conflict.Add(conf); } return(retVal); } catch (Exception e) { Trace.TraceError("Could not execute GetConflicts : {0}", e.ToString()); audit.Outcome = OutcomeIndicator.EpicFail; #if DEBUG throw new FaultException(new FaultReason(e.ToString()), new FaultCode(e.GetType().Name)); #else throw new FaultException(new FaultReason(e.Message), new FaultCode(e.GetType().Name)); #endif } finally { if (auditSvc != null) { auditSvc.SendAudit(audit); } } }
/// <summary> /// Handle a PIX query /// </summary> private IMessage HandlePixQuery(NHapi.Model.V25.Message.QBP_Q21 request, Hl7MessageReceivedEventArgs evt) { // Get config var config = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; var locale = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService; var dataService = this.Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService; // Create a details array List <IResultDetail> dtls = new List <IResultDetail>(); // Validate the inbound message MessageUtil.Validate((IMessage)request, config, dtls, this.Context); IMessage response = null; // Control if (request == null) { return(null); } // Construct appropriate audit AuditData audit = null; // Data controller AuditUtil auditUtil = new AuditUtil() { Context = this.Context }; //DataUtil dataUtil = new DataUtil() { Context = this.Context }; try { // Create Query Data ComponentUtility cu = new ComponentUtility() { Context = this.Context }; DeComponentUtility dcu = new DeComponentUtility() { Context = this.Context }; var data = cu.CreateQueryComponents(request, dtls); if (data == null) { throw new InvalidOperationException(locale.GetString("MSGE00A")); } RegistryQueryResult result = dataService.Query(data); dtls.AddRange(result.Details); // Update locations? foreach (var dtl in dtls) { if (dtl is PatientNotFoundResultDetail) { dtl.Location = "QPD^1^3^1^1"; } else if (dtl is UnrecognizedPatientDomainResultDetail) { dtl.Location = "QPD^1^3^1^4"; } else if (dtl is UnrecognizedTargetDomainResultDetail) { dtl.Location = "QPD^1^4^"; } } audit = auditUtil.CreateAuditData("ITI-9", ActionType.Execute, OutcomeIndicator.Success, evt, result); // Now process the result response = dcu.CreateRSP_K23(result, dtls); //var r = dcu.CreateRSP_K23(null, null); // Copy QPD try { (response as NHapi.Model.V25.Message.RSP_K23).QPD.MessageQueryName.Identifier.Value = request.QPD.MessageQueryName.Identifier.Value; Terser reqTerser = new Terser(request), rspTerser = new Terser(response); rspTerser.Set("/QPD-1", reqTerser.Get("/QPD-1")); rspTerser.Set("/QPD-2", reqTerser.Get("/QPD-2")); rspTerser.Set("/QPD-3-1", reqTerser.Get("/QPD-3-1")); rspTerser.Set("/QPD-3-4-1", reqTerser.Get("/QPD-3-4-1")); rspTerser.Set("/QPD-3-4-2", reqTerser.Get("/QPD-3-4-2")); rspTerser.Set("/QPD-3-4-3", reqTerser.Get("/QPD-3-4-3")); rspTerser.Set("/QPD-4-1", reqTerser.Get("/QPD-4-1")); rspTerser.Set("/QPD-4-4-1", reqTerser.Get("/QPD-4-4-1")); rspTerser.Set("/QPD-4-4-2", reqTerser.Get("/QPD-4-4-2")); rspTerser.Set("/QPD-4-4-3", reqTerser.Get("/QPD-4-4-3")); } catch (Exception e) { Trace.TraceError(e.ToString()); } //MessageUtil.((response as NHapi.Model.V25.Message.RSP_K23).QPD, request.QPD); MessageUtil.UpdateMSH(new NHapi.Base.Util.Terser(response), request, config); } catch (Exception e) { Trace.TraceError(e.ToString()); if (!dtls.Exists(o => o is UnrecognizedPatientDomainResultDetail || o is UnrecognizedTargetDomainResultDetail || o.Message == e.Message || o.Exception == e)) { dtls.Add(new ResultDetail(ResultDetailType.Error, e.Message, e)); } response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(RSP_K23)); Terser errTerser = new Terser(response); // HACK: Fix the generic ACK with a real ACK for this message errTerser.Set("/MSH-9-2", "K23"); errTerser.Set("/MSH-9-3", "RSP_K23"); errTerser.Set("/QAK-2", "AE"); errTerser.Set("/MSA-1", "AE"); errTerser.Set("/QAK-1", request.QPD.QueryTag.Value); audit = auditUtil.CreateAuditData("ITI-9", ActionType.Execute, OutcomeIndicator.EpicFail, evt, new List <VersionedDomainIdentifier>()); } finally { IAuditorService auditSvc = this.Context.GetService(typeof(IAuditorService)) as IAuditorService; if (auditSvc != null) { auditSvc.SendAudit(audit); } } return(response); }
/// <summary> /// Handle a PIX admission /// </summary> private IMessage HandlePixAdmit(NHapi.Model.V231.Message.ADT_A01 request, Hl7MessageReceivedEventArgs evt) { // Get config var config = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; var locale = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService; var dataService = this.Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService; // Create a details array List <IResultDetail> dtls = new List <IResultDetail>(); // Validate the inbound message MessageUtil.Validate((IMessage)request, config, dtls, this.Context); IMessage response = null; // Control if (request == null) { return(null); } // Data controller AuditUtil auditUtil = new AuditUtil() { Context = this.Context }; //DataUtil dataUtil = new DataUtil() { Context = this.Context }; // Construct appropriate audit AuditData audit = null; try { // Create Query Data ComponentUtility cu = new ComponentUtility() { Context = this.Context }; DeComponentUtility dcu = new DeComponentUtility() { Context = this.Context }; var data = cu.CreateComponents(request, dtls); if (data == null) { throw new InvalidOperationException(locale.GetString("MSGE00A")); } var result = dataService.Register(data, request.MSH.ProcessingID.ProcessingID.Value == "P" ? DataPersistenceMode.Production : DataPersistenceMode.Debugging); if (result == null || result.VersionId == null) { throw new InvalidOperationException(locale.GetString("DTPE001")); } dtls.AddRange(result.Details); audit = auditUtil.CreateAuditData("ITI-8", result.VersionId.UpdateMode == UpdateModeType.Update ? ActionType.Update : ActionType.Create, OutcomeIndicator.Success, evt, new List <VersionedDomainIdentifier>() { result.VersionId }); // Now process the result response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(NHapi.Model.V231.Message.ACK)); MessageUtil.UpdateMSH(new NHapi.Base.Util.Terser(response), request, config); (response as NHapi.Model.V231.Message.ACK).MSH.MessageType.TriggerEvent.Value = request.MSH.MessageType.TriggerEvent.Value; (response as NHapi.Model.V231.Message.ACK).MSH.MessageType.MessageType.Value = "ACK"; } catch (Exception e) { Trace.TraceError(e.ToString()); if (!dtls.Exists(o => o.Message == e.Message || o.Exception == e)) { dtls.Add(new ResultDetail(ResultDetailType.Error, e.Message, e)); } response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(NHapi.Model.V231.Message.ACK)); audit = auditUtil.CreateAuditData("ITI-8", ActionType.Create, OutcomeIndicator.EpicFail, evt, new List <VersionedDomainIdentifier>()); } finally { IAuditorService auditSvc = this.Context.GetService(typeof(IAuditorService)) as IAuditorService; if (auditSvc != null) { auditSvc.SendAudit(audit); } } return(response); }
/// <summary> /// Handle the PIX merge request /// </summary> private IMessage HandlePixMerge(NHapi.Model.V231.Message.ADT_A39 request, Hl7MessageReceivedEventArgs evt) { // Get config var config = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; var locale = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService; var dataService = this.Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService; // Create a details array List <IResultDetail> dtls = new List <IResultDetail>(); // Validate the inbound message MessageUtil.Validate((IMessage)request, config, dtls, this.Context); IMessage response = null; // Control if (request == null) { return(null); } // Data controller //DataUtil dataUtil = new DataUtil() { Context = this.Context }; AuditUtil auditUtil = new AuditUtil() { Context = this.Context }; // Construct appropriate audit List <AuditData> audit = new List <AuditData>(); try { // Create Query Data ComponentUtility cu = new ComponentUtility() { Context = this.Context }; DeComponentUtility dcu = new DeComponentUtility() { Context = this.Context }; var data = cu.CreateComponents(request, dtls); if (data == null) { throw new InvalidOperationException(locale.GetString("MSGE00A")); } // Merge var result = dataService.Merge(data, request.MSH.ProcessingID.ProcessingID.Value == "P" ? DataPersistenceMode.Production : DataPersistenceMode.Debugging); if (result == null || result.VersionId == null) { throw new InvalidOperationException(locale.GetString("DTPE001")); } List <VersionedDomainIdentifier> deletedRecordIds = new List <VersionedDomainIdentifier>(), updatedRecordIds = new List <VersionedDomainIdentifier>(); // Subjects var oidData = config.OidRegistrar.GetOid("CR_CID").Oid; foreach (Person subj in data.FindAllComponents(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf)) { PersonRegistrationRef replcd = subj.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.ReplacementOf) as PersonRegistrationRef; deletedRecordIds.Add(new VersionedDomainIdentifier() { Identifier = replcd.Id.ToString(), Domain = oidData }); updatedRecordIds.Add(new VersionedDomainIdentifier() { Identifier = subj.Id.ToString(), Domain = oidData }); } // Now audit audit.Add(auditUtil.CreateAuditData("ITI-8", ActionType.Delete, OutcomeIndicator.Success, evt, deletedRecordIds)); audit.Add(auditUtil.CreateAuditData("ITI-8", ActionType.Update, OutcomeIndicator.Success, evt, updatedRecordIds)); // Now process the result response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(NHapi.Model.V231.Message.ACK)); MessageUtil.UpdateMSH(new NHapi.Base.Util.Terser(response), request, config); (response as NHapi.Model.V231.Message.ACK).MSH.MessageType.TriggerEvent.Value = request.MSH.MessageType.TriggerEvent.Value; (response as NHapi.Model.V231.Message.ACK).MSH.MessageType.MessageType.Value = "ACK"; } catch (Exception e) { Trace.TraceError(e.ToString()); if (!dtls.Exists(o => o.Message == e.Message || o.Exception == e)) { dtls.Add(new ResultDetail(ResultDetailType.Error, e.Message, e)); } response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(NHapi.Model.V231.Message.ACK)); audit.Add(auditUtil.CreateAuditData("ITI-8", ActionType.Delete, OutcomeIndicator.EpicFail, evt, new List <VersionedDomainIdentifier>())); } finally { IAuditorService auditSvc = this.Context.GetService(typeof(IAuditorService)) as IAuditorService; if (auditSvc != null) { foreach (var aud in audit) { auditSvc.SendAudit(aud); } } } return(response); }
/// <summary> /// Fired whenever a message is available for processing /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void connector_MessageAvailable(object sender, UnsolicitedDataEventArgs e) { // Audit service IAuditorService auditService = Context.GetService(typeof(IAuditorService)) as IAuditorService; #region Setup Audit AuditData audit = new AuditData( DateTime.Now, ActionType.Execute, OutcomeIndicator.Success, EventIdentifierType.ApplicationActivity, new AuditCode("GEN", null) ); audit.Actors.Add(new AuditActorData() { NetworkAccessPointId = Environment.MachineName, NetworkAccessPointType = NetworkAccessPointType.MachineName, UserIdentifier = String.Format("{0}\\{1}", Environment.UserDomainName, Environment.UserName) }); audit.Actors.Add(new AuditActorData() { UserIsRequestor = true, NetworkAccessPointId = e.SolicitorEndpoint.ToString(), NetworkAccessPointType = NetworkAccessPointType.IPAddress, UserIdentifier = e.SolicitorEndpoint.ToString() }); audit.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.Uri, LifecycleType = AuditableObjectLifecycle.Access, Role = AuditableObjectRole.DataRepository, ObjectId = e.ReceiveEndpoint.ToString(), Type = AuditableObjectType.SystemObject }); #endregion try { // Find a receiver capable of processing this var wcfConnector = (sender as IListenWaitConnector); IReceiveResult rcvResult = wcfConnector.Receive(); // get the persistence service from the context IMessagePersistenceService persistenceService = Context.GetService(typeof(IMessagePersistenceService)) as IMessagePersistenceService; // Were we able to process the message Assembly messageTypeAssembly = null; if (rcvResult.Structure != null) { messageTypeAssembly = rcvResult.Structure.GetType().Assembly; } // Find the configuration section that handles the specified revision var curRevision = m_configuration.Revisions.Find(o => o.Listeners.Exists(l => l.ConnectionString == wcfConnector.ConnectionString)); if (curRevision == null) { Trace.TraceError("This service does not seem to have support for the version of message being used"); throw new UninterpretableMessageException("This service doesn't support this standard", rcvResult); } // Do we have a handler for this message interaction? Cast as an interaction // and attempt to find the handler configuration IInteraction interactionStructure = rcvResult.Structure as IInteraction; MessageHandlerConfiguration receiverConfig = null; if (interactionStructure != null && interactionStructure.InteractionId != null && !String.IsNullOrEmpty(interactionStructure.InteractionId.Extension)) { receiverConfig = curRevision.MessageHandlers.Find(o => o.Interactions.Exists(i => i.Id == interactionStructure.InteractionId.Extension)); } else { Trace.TraceWarning("Interaction is missing InteractionId attribute! Assuming default"); // Set interaction id var intId = interactionStructure.GetType().GetMethod("GetInteractionId", BindingFlags.Static | BindingFlags.Public); if (intId == null) { throw new InvalidOperationException("Cannot find the GetInteractionId method, cannot determine interaction"); } interactionStructure.InteractionId = intId.Invoke(null, null) as II; } // Message identifier missing? if (interactionStructure.Id == null) { interactionStructure.Id = Guid.NewGuid(); Trace.TraceWarning("Interaction is missing id. Generated token {0}...", interactionStructure.Id.Root); } IEverestMessageReceiver currentHandler = null, defaultHandler = null; var defaultHandlerConfig = curRevision.MessageHandlers.Find(o => o.Interactions.Exists(i => i.Id == "*")); receiverConfig = receiverConfig ?? defaultHandlerConfig; // find a handler // Receiver configuration if (receiverConfig == null) { throw new InvalidOperationException("Cannot find appropriate handler this message"); } else { var messageState = Core.Services.MessageState.New; IInteraction response = null; InteractionConfiguration interactionConfig = receiverConfig.Interactions.Find(o => o.Id == interactionStructure.InteractionId.Extension); if (interactionConfig != null && interactionConfig.Disclosure) { persistenceService = null; } // check with persistence if (persistenceService != null) { messageState = persistenceService.GetMessageState(String.Format(curRevision.MessageIdentifierFormat, interactionStructure.Id.Root, interactionStructure.Id.Extension)); } switch (messageState) { case Core.Services.MessageState.New: // Persist the message if (persistenceService != null) { MemoryStream ms = new MemoryStream(); try { WriteMessageToStream(sender as IFormattedConnector, interactionStructure, ms); persistenceService.PersistMessage(String.Format(curRevision.MessageIdentifierFormat, interactionStructure.Id.Root, interactionStructure.Id.Extension), ms); } finally { ms.Dispose(); } } currentHandler = receiverConfig.Handler; defaultHandler = defaultHandlerConfig.Handler; response = currentHandler.HandleMessageReceived(sender, e, rcvResult) as IInteraction; if (persistenceService != null) { MemoryStream ms = new MemoryStream(); try { WriteMessageToStream(sender as IFormattedConnector, response, ms); persistenceService.PersistResultMessage(String.Format(curRevision.MessageIdentifierFormat, response.Id.Root, response.Id.Extension), String.Format(curRevision.MessageIdentifierFormat, interactionStructure.Id.Root, interactionStructure.Id.Extension), ms); } finally { ms.Dispose(); } } break; case Core.Services.MessageState.Complete: var rms = persistenceService.GetMessageResponseMessage(String.Format(curRevision.MessageIdentifierFormat, interactionStructure.Id.Root, interactionStructure.Id.Extension)); var parseResult = (sender as IFormattedConnector).Formatter.Parse(rms); response = parseResult.Structure as IInteraction; break; case Core.Services.MessageState.Active: throw new ApplicationException("Message is already being processed"); } // Send back IListenWaitRespondConnector ilwConnector = sender as IListenWaitRespondConnector; if (ilwConnector == null) // no need to send something back { auditService.SendAudit(audit); return; } else { // Invalid message delegate var invalidMessageDelegate = new EventHandler <MessageEventArgs>(delegate(object sndr, MessageEventArgs mea) { audit.Outcome = OutcomeIndicator.MinorFail; InvalidMessageResult res = new InvalidMessageResult() { Code = mea.Code, Details = mea.Details, Structure = rcvResult.Structure }; if (defaultHandler != null) { mea.Alternate = response; } Trace.TraceWarning("Returning a default message because Everest was unable to serialize the response correctly. Error was {0}", mea.Code); Trace.Indent(); foreach (IResultDetail dtl in mea.Details) { Trace.TraceWarning("{0} : {1} : {2}", dtl.Type, dtl.Message, dtl.Location); } Trace.Unindent(); mea.Alternate = response; }); ilwConnector.InvalidResponse += invalidMessageDelegate; try { // Create headers var wcfResult = rcvResult as WcfReceiveResult; if (wcfResult != null && wcfResult.Headers != null) { var rcvrInfo = receiverConfig.Interactions.Find(o => o.Id == interactionStructure.InteractionId.Extension); if (rcvrInfo != null) { wcfResult.ResponseHeaders = CreateResponseHeaders(rcvrInfo.ResponseHeaders, wcfResult.Headers.MessageVersion); } if (wcfResult.ResponseHeaders != null) { wcfResult.ResponseHeaders.RelatesTo = wcfResult.Headers.MessageId; } } ISendResult sndResult = ilwConnector.Send(response, rcvResult); if (sndResult.Code != ResultCode.Accepted && sndResult.Code != ResultCode.AcceptedNonConformant) { Trace.TraceError("Cannot send response back to the solicitor : {0}", sndResult.Code); Trace.Indent(); foreach (IResultDetail dtl in sndResult.Details ?? new IResultDetail[0]) { Trace.TraceError("{0}: {1} : {2}", dtl.Type, dtl.Message, dtl.Location); } Trace.Unindent(); } } finally { if (auditService != null) { auditService.SendAudit(audit); } // Remove the invalid message delegate ilwConnector.InvalidResponse -= invalidMessageDelegate; } } } } catch (System.Exception ex) { #region Audit Failure audit.Outcome = OutcomeIndicator.EpicFail; if (auditService != null) { auditService.SendAudit(audit); } #endregion Trace.TraceError(ex.ToString()); throw; } }
/// <summary> /// Handle the pdq query /// </summary> private IMessage HandlePdqQuery(QBP_Q21 request, Hl7MessageReceivedEventArgs evt) { // Get config var config = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; var locale = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService; var dataService = this.Context.GetService(typeof(IClientRegistryDataService)) as IClientRegistryDataService; // Create a details array List <IResultDetail> dtls = new List <IResultDetail>(); // Validate the inbound message MessageUtil.Validate((IMessage)request, config, dtls, this.Context); IMessage response = null; // Control if (request == null) { return(null); } // Data controller //DataUtil dataUtil = new DataUtil() { Context = this.Context }; AuditUtil auditUtil = new AuditUtil() { Context = this.Context }; // Construct appropriate audit AuditData audit = null; try { // Create Query Data ComponentUtility cu = new ComponentUtility() { Context = this.Context }; DeComponentUtility dcu = new DeComponentUtility() { Context = this.Context }; var data = cu.CreateQueryComponentsPdq(request, dtls); if (data == null) { Trace.TraceError("{0} problems mapping message:", dtls.Count); foreach (var itm in dtls) { Trace.TraceError($"\t{itm.Type} : {itm.Message}"); } throw new InvalidOperationException();// locale?.GetString("MSGE00A") ?? "Could not process components"); } // Is this a continue or new query? RegistryQueryResult result = dataService.Query(data); audit = auditUtil.CreateAuditData("ITI-21", ActionType.Execute, OutcomeIndicator.Success, evt, result); // Now process the result response = dcu.CreateRSP_K21(result, data, dtls); //MessageUtil.CopyQPD((response as RSP_K21).QPD, request.QPD, data); MessageUtil.UpdateMSH(new NHapi.Base.Util.Terser(response), request, config); Terser ters = new Terser(response); ters.Set("/MSH-9-2", "K22"); } catch (Exception e) { Trace.TraceError(e.ToString()); if (!dtls.Exists(o => o.Message == e.Message || o.Exception == e)) { if (dtls.Count == 0) { dtls.Add(new ResultDetail(ResultDetailType.Error, e.Message, e)); } } // HACK: Only one error allowed in nHAPI for some reason : // TODO: Fix NHapi dtls.RemoveAll(o => o.Type != ResultDetailType.Error); while (dtls.Count > 1) { dtls.RemoveAt(1); } response = MessageUtil.CreateNack(request, dtls, this.Context, typeof(RSP_K21)); Terser errTerser = new Terser(response); // HACK: Fix the generic ACK with a real ACK for this message errTerser.Set("/MSH-9-2", "K22"); errTerser.Set("/MSH-9-3", "RSP_K21"); errTerser.Set("/QAK-2", "AE"); errTerser.Set("/MSA-1", "AE"); errTerser.Set("/QAK-1", request.QPD.QueryTag.Value); audit = auditUtil.CreateAuditData("ITI-21", ActionType.Execute, OutcomeIndicator.EpicFail, evt, new List <VersionedDomainIdentifier>()); } finally { IAuditorService auditSvc = this.Context.GetService(typeof(IAuditorService)) as IAuditorService; if (auditSvc != null) { auditSvc.SendAudit(audit); } } return(response); }