/// <summary> /// Internal notification logic /// </summary> private void NotifyInternal(object state) { // Get the state try { NotificationQueueWorkItem workItem = state as NotificationQueueWorkItem; ILocalizationService locale = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService; IDataPersistenceService idps = this.Context.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService; if (workItem == null) { throw new ArgumentException("workItem"); } var evt = workItem.Event; if (idps != null) { evt = idps.GetContainer(workItem.Event.AlternateIdentifier, true) as RegistrationEvent; } var subject = workItem.Event.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person; if (subject == null) { throw new InvalidOperationException(locale.GetString("NTFE001")); } // Now determine who will receive updates Trace.TraceInformation("Searching for targets for patient notification..."); List <TargetConfiguration> targets = null; lock (s_syncLock) { targets = s_configuration.Targets.FindAll(o => o.NotificationDomain.Exists(delegate(NotificationDomainConfiguration dc) { bool action = dc.Actions.Exists(act => (act.Action & workItem.Action) == workItem.Action); bool domain = dc.Domain == "*" || subject.AlternateIdentifiers.Exists(id => id.Domain == dc.Domain); return(action && domain); } )); } Trace.TraceInformation("{0} targets for patient notification found..."); // Notify the targets foreach (var itm in targets) { itm.Notifier.Context = this.Context; itm.Notifier.Notify(workItem); } } catch (Exception e) { Trace.TraceError(e.ToString()); } }
/// <summary> /// Notify the operation /// </summary> public void Notify(NotificationQueueWorkItem workItem) { // configuration service ISystemConfigurationService config = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; ILocalizationService locale = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService; // Common message bits we need to update IMessage notificationMessage = null; MSH msh = null; PID pid = null; EVN evn = null; PV1 pv1 = null; // Identify the work item action switch (workItem.Action) { case MARC.HI.EHRS.CR.Notification.PixPdq.Configuration.ActionType.Create: case MARC.HI.EHRS.CR.Notification.PixPdq.Configuration.ActionType.DuplicatesResolved: case MARC.HI.EHRS.CR.Notification.PixPdq.Configuration.ActionType.Update: { ADT_A05 message = new ADT_A05(); msh = message.MSH; pid = message.PID; evn = message.EVN; pv1 = message.PV1; notificationMessage = message; msh.MessageType.TriggerEvent.Value = "A31"; break; } } // Populate the MSH header first this.UpdateMSH(msh, config); // Populate the EVN segment evn.EventTypeCode.Value = workItem.Event.Mode.ToString(); evn.RecordedDateTime.Time.Value = (TS)workItem.Event.Timestamp; // Populate the PID segment Person subject = workItem.Event.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person; this.UpdatePID(subject, pid, config); pv1.PatientClass.Value = "N"; // Send var queueItem = new Hl7MessageQueue.MessageQueueWorkItem(this.Target, notificationMessage); if (!queueItem.TrySend()) { Trace.TraceWarning(locale.GetString("NTFW005")); Hl7MessageQueue.Current.EnqueueMessageItem(queueItem); } }
/// <summary> /// Notify the operation /// </summary> public void Notify(NotificationQueueWorkItem workItem) { // configuration service ISystemConfigurationService config = this.Context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService; ILocalizationService locale = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService; // Common message bits we need to update IMessage notificationMessage = null; MSH msh = null; PID pid = null; EVN evn = null; PV1 pv1 = null; MRG mrg = null; // Identify the work item action switch (workItem.Action) { case MARC.HI.EHRS.CR.Notification.PixPdq.Configuration.ActionType.Create: { ADT_A01 message = new ADT_A01(); msh = message.MSH; pid = message.PID; evn = message.EVN; pv1 = message.PV1; notificationMessage = message; msh.MessageType.TriggerEvent.Value = "A04"; break; } case MARC.HI.EHRS.CR.Notification.PixPdq.Configuration.ActionType.DuplicatesResolved: { ADT_A39 message = new ADT_A39(); msh = message.MSH; msh.MessageType.TriggerEvent.Value = "A40"; pid = message.GetPATIENT(0).PID; evn = message.EVN; pv1 = message.GetPATIENT(0).PV1; mrg = message.GetPATIENT(0).MRG; notificationMessage = message; break; }; case MARC.HI.EHRS.CR.Notification.PixPdq.Configuration.ActionType.Update: { ADT_A01 message = new ADT_A01(); msh = message.MSH; pid = message.PID; evn = message.EVN; pv1 = message.PV1; notificationMessage = message; msh.MessageType.TriggerEvent.Value = "A08"; break; } } // Populate the MSH header first this.UpdateMSH(msh, config); // Populate the EVN segment evn.EventTypeCode.Value = workItem.Event.Mode.ToString(); evn.RecordedDateTime.TimeOfAnEvent.Value = (TS)workItem.Event.Timestamp; // Populate the PID segment Person subject = workItem.Event.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person; this.UpdatePID(subject, pid, config); pv1.PatientClass.Value = "I"; // Populate MRG if (mrg != null) { var registration = this.Context.GetService(typeof(IDataRegistrationService)) as IDataRegistrationService; var persistence = this.Context.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService; var replacements = subject.FindAllComponents(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.ReplacementOf); foreach (PersonRegistrationRef rplc in replacements) { // First, need to de-persist the identifiers QueryParameters qp = new QueryParameters() { Confidence = 1.0f, MatchingAlgorithm = MatchAlgorithm.Exact, MatchStrength = MatchStrength.Exact }; var queryEvent = new QueryEvent(); var patientQuery = new RegistrationEvent(); queryEvent.Add(qp, "FLT", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.FilterOf, null); patientQuery.Add(new Person() { AlternateIdentifiers = rplc.AlternateIdentifiers }, "SUBJ", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf, null); queryEvent.Add(patientQuery, "SUBJ", SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf, null); // Perform the query var patientIdentifiers = registration.QueryRecord(queryEvent); if (patientIdentifiers.Length == 0) { throw new InvalidOperationException(); } var replacedPerson = (persistence.GetContainer(patientIdentifiers[0], true) as RegistrationEvent).FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person; foreach (var ii in replacedPerson.AlternateIdentifiers.FindAll(o => this.Target.NotificationDomain.Exists(d => d.Domain == o.Domain))) { var cx = mrg.GetPriorPatientIdentifierList(mrg.PriorAlternatePatientIDRepetitionsUsed); cx.ID.Value = ii.Identifier; if (String.IsNullOrEmpty(ii.AssigningAuthority)) { cx.AssigningAuthority.NamespaceID.Value = config.OidRegistrar.FindData(ii.Domain).Attributes.Find(o => o.Key == "AssigningAuthorityName").Value; } else { cx.AssigningAuthority.NamespaceID.Value = ii.AssigningAuthority; } cx.AssigningAuthority.UniversalID.Value = ii.Domain; cx.AssigningAuthority.UniversalIDType.Value = "ISO"; } } } // Send var queueItem = new Hl7MessageQueue.MessageQueueWorkItem(this.Target, notificationMessage); if (!queueItem.TrySend()) { Trace.TraceWarning(locale.GetString("NTFW005")); Hl7MessageQueue.Current.EnqueueMessageItem(queueItem); } }
/// <summary> /// Notify the target system /// </summary> public void Notify(NotificationQueueWorkItem workItem) { ILocalizationService locale = this.Context.GetService(typeof(ILocalizationService)) as ILocalizationService; // Create a message utility MessageUtility msgUtil = new MessageUtility() { Context = this.Context }; // Create the EV formatters XmlIts1Formatter formatter = new XmlIts1Formatter() { ValidateConformance = false }; formatter.GraphAides.Add(new DatatypeFormatter() { ValidateConformance = false }); // Iterate through the targets attempting to notify each one using (WcfClientConnector wcfClient = new WcfClientConnector(this.Target.ConnectionString)) { wcfClient.Formatter = formatter; wcfClient.Open(); // Build the message Trace.TraceInformation("Sending notification to '{0}'...", this.Target.Name); IInteraction notification = msgUtil.CreateMessage(workItem.Event, ActionType.Update, this.Target); // Send it var sendResult = wcfClient.Send(notification); if (sendResult.Code != Everest.Connectors.ResultCode.Accepted && sendResult.Code != Everest.Connectors.ResultCode.AcceptedNonConformant) { Trace.TraceWarning(string.Format(locale.GetString("NTFW002"), this.Target.Name)); DumpResultDetails(sendResult.Details); return; } // Receive the response var rcvResult = wcfClient.Receive(sendResult); if (rcvResult.Code != Everest.Connectors.ResultCode.Accepted && rcvResult.Code != Everest.Connectors.ResultCode.AcceptedNonConformant) { Trace.TraceWarning(string.Format(locale.GetString("NTFW003"), this.Target.Name)); DumpResultDetails(rcvResult.Details); return; } // Get structure var response = rcvResult.Structure as MCCI_IN000002UV01; if (response == null) { Trace.TraceWarning(string.Format(locale.GetString("NTFW003"), this.Target.Name)); return; } if (response.Acknowledgement.Count == 0 || response.Acknowledgement[0].TypeCode != AcknowledgementType.AcceptAcknowledgementCommitAccept) { Trace.TraceWarning(string.Format(locale.GetString("NTFW004"), this.Target.Name)); return; } // Close the connector and continue wcfClient.Close(); } }