static void connector_MessageAvailable(object sender, UnsolicitedDataEventArgs args) { // Start the receive operation (starts on another thread) IAsyncResult iar = (sender as FileListenConnector).BeginReceive(null, null); iar.AsyncWaitHandle.WaitOne(); // Wait until complete FileReceiveResult result = (sender as FileListenConnector).EndReceive(iar) as FileReceiveResult; Console.WriteLine("Received file: {0}", result.FileName); if (result.Details.Length > 0) { Console.WriteLine("The following {0} errors were encountered: ", result.Details.Length.ToString()); foreach (MARC.Everest.Connectors.ResultDetail r in result.Details) { Console.WriteLine(r.Message.ToString()); } } Console.WriteLine("Processing complete"); }
private void watcher_Created(object sender, FileSystemEventArgs e) { // Ensure we can process this message if (pattern != null) { //TODO: TD: Should use a cached copy of the regex // Get the filename and see if it matches our pattern Regex r = new Regex(pattern); if (r.IsMatch(e.Name) && System.IO.File.Exists(e.FullPath)) { // Open for read Stream s = null; try { lock (waitingData) { waitingData.Enqueue(e.FullPath); } // Add the buffer to the queue of items to be received // Data event args UnsolicitedDataEventArgs usdea = new UnsolicitedDataEventArgs( new Uri(string.Format("file://{0}/{1}", this.directory, e.Name)), DateTime.Now, null); // Call the delegate that handles processing, if there is one if (MessageAvailable != null) { MessageAvailable(this, usdea); } } finally { if (s != null) { s.Close(); // Close the file } } } } }
/// <summary> /// Begin a notification of message received, returns a correlation. /// </summary> /// <returns>A guid that represents the unique identifier for the message in the receiver.</returns> internal WcfSendResult ProcessMessage(Message m) { Guid rGuid = Guid.NewGuid(); // Unique identifier #if DEBUG Trace.TraceInformation("Enqueuing message..."); #endif // Start notification lock (waitingMessages) waitingMessages.Enqueue(new KeyValuePair<Message, Guid>(m, rGuid)); // Publish a wait handle WaitHandle wait = new AutoResetEvent(false); lock (waitHandles) waitHandles.Add(rGuid, wait); // Create unsolicited data event args var rep = (OperationContext.Current.IncomingMessageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty); // JF - To handle IPv6 processing Uri uriFrom = m.Headers.From != null ? m.Headers.From.Uri : null; if(uriFrom == null) { // Attempt to do reverse lookup try { var address = IPAddress.Parse(rep.Address); uriFrom = new Uri(String.Format("http://{0}:{1}", rep.Address, rep.Port)); } catch { #if DEBUG Trace.TraceInformation("Performance: Exception while resolving host name"); #endif uriFrom = new Uri("http://anonymous"); } } UnsolicitedDataEventArgs usdea = new UnsolicitedDataEventArgs(m.Headers.To, DateTime.Now, uriFrom); // Message is available if (MessageAvailable != null) { #if DEBUG Trace.TraceInformation("Raising MessageAvailable event"); #endif MessageAvailable(this, usdea); // Start to invoke on another thread... we don't care what the result it } wait.WaitOne(new TimeSpan(0, 1, 0)); // TODO: How to reliably detect no one is going to send a result // Get the result WcfSendResult retVal; if (results.TryGetValue(rGuid, out retVal)) { lock (results) results.Remove(rGuid); return retVal; } // //return null; throw new InvalidAsynchronousStateException( String.Format("Response message for msg '{0}' recevied by WcfServerConnector, but couldn't be found in the results", rGuid)); }
/// <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> /// 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> /// Begin a notification of message received, returns a correlation. /// </summary> /// <returns>A guid that represents the unique identifier for the message in the receiver.</returns> internal WcfSendResult ProcessMessage(Message m) { Guid rGuid = Guid.NewGuid(); // Unique identifier #if DEBUG Trace.TraceInformation("Enqueuing message..."); #endif // Start notification lock (waitingMessages) waitingMessages.Enqueue(new KeyValuePair <Message, Guid>(m, rGuid)); // Publish a wait handle WaitHandle wait = new AutoResetEvent(false); lock (waitHandles) waitHandles.Add(rGuid, wait); // Create unsolicited data event args var rep = (OperationContext.Current.IncomingMessageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty); // JF - To handle IPv6 processing Uri uriFrom = m.Headers.From != null ? m.Headers.From.Uri : null; if (uriFrom == null) { // Attempt to do reverse lookup try { var address = IPAddress.Parse(rep.Address); uriFrom = new Uri(String.Format("http://{0}:{1}", rep.Address, rep.Port)); } catch { #if DEBUG Trace.TraceInformation("Performance: Exception while resolving host name"); #endif uriFrom = new Uri("http://anonymous"); } } UnsolicitedDataEventArgs usdea = new UnsolicitedDataEventArgs(m.Headers.To, DateTime.Now, uriFrom); // Message is available if (MessageAvailable != null) { #if DEBUG Trace.TraceInformation("Raising MessageAvailable event"); #endif MessageAvailable(this, usdea); // Start to invoke on another thread... we don't care what the result it } wait.WaitOne(new TimeSpan(0, 1, 0)); // TODO: How to reliably detect no one is going to send a result // Get the result WcfSendResult retVal; if (results.TryGetValue(rGuid, out retVal)) { lock (results) results.Remove(rGuid); return(retVal); } // //return null; throw new InvalidAsynchronousStateException( String.Format("Response message for msg '{0}' recevied by WcfServerConnector, but couldn't be found in the results", rGuid)); }
private void watcher_Created(object sender, FileSystemEventArgs e) { // Ensure we can process this message if (pattern != null) { //TODO: TD: Should use a cached copy of the regex // Get the filename and see if it matches our pattern Regex r = new Regex(pattern); if (r.IsMatch(e.Name) && System.IO.File.Exists(e.FullPath)) { // Open for read Stream s = null; try { lock (waitingData) { waitingData.Enqueue(e.FullPath); } // Add the buffer to the queue of items to be received // Data event args UnsolicitedDataEventArgs usdea = new UnsolicitedDataEventArgs( new Uri(string.Format("file://{0}/{1}", this.directory, e.Name)), DateTime.Now, null); // Call the delegate that handles processing, if there is one if (MessageAvailable != null) MessageAvailable(this, usdea); } finally { if (s != null) s.Close(); // Close the file } } } }
// Delegate handles the message available event static void connector_MessageAvailable(object sender, UnsolicitedDataEventArgs e) { // Cast connector WcfServerConnector connector = sender as WcfServerConnector; connector.InvalidResponse += new EventHandler <MessageEventArgs>(connector_InvalidResponse); // Receive the structure WcfReceiveResult rcvResult = connector.Receive() as WcfReceiveResult; if (rcvResult.Structure != null) { Console.WriteLine(rcvResult.Structure.GetType().Name); } // Prepare acknowledgement structure Acknowledgement acknowledgement = new Acknowledgement(); // Assign the correlation acknowledgement.TargetMessage = new TargetMessage( (rcvResult.Structure as IIdentifiable).Id ); // Determine the deserialization outcome if (rcvResult.Code != ResultCode.Accepted && rcvResult.Code != ResultCode.AcceptedNonConformant) { // There were problems parsing the request message acknowledgement.TypeCode = AcknowledgementType.AcceptAcknowledgementCommitError; } else { // Message is all good acknowledgement.TypeCode = AcknowledgementType.AcceptAcknowledgementCommitAccept; } // Append all details foreach (IResultDetail dtl in rcvResult.Details) { AcknowledgementDetail detail = new AcknowledgementDetail( AcknowledgementDetailType.Information, AcknowledgementDetailCode.SyntaxError, dtl.Message, new SET <ST>((ST)dtl.Location) ); acknowledgement.AcknowledgementDetail.Add(detail); } // Create a response MCCI_IN000002CA response = new MCCI_IN000002CA( new II(Guid.NewGuid()), DateTime.Now, ResponseMode.Immediate, MCCI_IN000002CA.GetInteractionId(), MCCI_IN000002CA.GetProfileId(), ProcessingID.Production, AcknowledgementCondition.Never, new Receiver( new Device2( new II() ) ), new Sender( new Device1( new II("1.1.1.1.1") ) ), acknowledgement ); // Send the result connector.Send(response, rcvResult); }
/// <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> /// Create audit data /// </summary> public AuditData CreateAuditData(string itiName, ActionType action, OutcomeIndicator outcome, UnsolicitedDataEventArgs msgEvent, IReceiveResult msgReceiveResult, IEnumerable <VersionedDomainIdentifier> patientRecord, HealthcareParticipant author) { // Audit data AuditData retVal = null; AuditableObjectLifecycle lifecycle = AuditableObjectLifecycle.Access; var wcfReceiveResult = msgReceiveResult as WcfReceiveResult; var msgReplyTo = wcfReceiveResult == null || wcfReceiveResult.Headers == null || wcfReceiveResult.Headers.ReplyTo == null?msgEvent.SolicitorEndpoint.ToString() : wcfReceiveResult.Headers.ReplyTo.Uri.ToString(); string userId = String.Empty; if (OperationContext.Current.Channel.RemoteAddress != null && OperationContext.Current.Channel.RemoteAddress.Uri != null) { userId = OperationContext.Current.Channel.RemoteAddress.Uri.OriginalString; } else if (OperationContext.Current.ServiceSecurityContext != null && OperationContext.Current.ServiceSecurityContext.PrimaryIdentity != null) { userId = OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name; } switch (itiName) { case "PRPA_TE101103CA": { retVal = new AuditData(DateTime.Now, action, outcome, EventIdentifierType.PatientRecord, new CodeValue(itiName, "HL7 Trigger Events")); // Audit actor for Patient Identity Source retVal.Actors.Add(new AuditActorData() { UserIsRequestor = true, UserIdentifier = msgReplyTo, ActorRoleCode = new List <CodeValue>() { new CodeValue("110153", "DCM") { DisplayName = "Source" } }, NetworkAccessPointId = msgEvent.SolicitorEndpoint.Host, NetworkAccessPointType = msgEvent.SolicitorEndpoint.HostNameType == UriHostNameType.Dns ? NetworkAccessPointType.MachineName : NetworkAccessPointType.IPAddress, UserName = userId }); // Audit actor for PIX manager retVal.Actors.Add(new AuditActorData() { UserIdentifier = msgEvent.ReceiveEndpoint.ToString(), UserIsRequestor = false, ActorRoleCode = new List <CodeValue>() { new CodeValue("110152", "DCM") { DisplayName = "Destination" } }, NetworkAccessPointType = NetworkAccessPointType.MachineName, NetworkAccessPointId = Dns.GetHostName(), AlternativeUserId = Process.GetCurrentProcess().Id.ToString() }); var request = msgReceiveResult.Structure as MARC.Everest.RMIM.CA.R020403.Interactions.PRPA_IN101103CA; retVal.AuditableObjects.Add(new AuditableObject() { Type = AuditableObjectType.SystemObject, Role = AuditableObjectRole.Query, IDTypeCode = AuditableObjectIdType.SearchCritereon, QueryData = Convert.ToBase64String(SerializeQuery(request.controlActEvent.QueryByParameter)), ObjectId = String.Format("{1}^^^&{0}&ISO", request.controlActEvent.QueryByParameter.QueryId.Root, request.controlActEvent.QueryByParameter.QueryId.Extension) }); break; } case "PRPA_TE101101CA": { retVal = new AuditData(DateTime.Now, action, outcome, EventIdentifierType.PatientRecord, new CodeValue(itiName, "HL7 Trigger Events")); // Audit actor for Patient Identity Source retVal.Actors.Add(new AuditActorData() { UserIsRequestor = true, UserIdentifier = msgReplyTo, ActorRoleCode = new List <CodeValue>() { new CodeValue("110153", "DCM") { DisplayName = "Source" } }, NetworkAccessPointId = msgEvent.SolicitorEndpoint.Host, NetworkAccessPointType = msgEvent.SolicitorEndpoint.HostNameType == UriHostNameType.Dns ? NetworkAccessPointType.MachineName : NetworkAccessPointType.IPAddress, UserName = userId }); // Audit actor for PIX manager retVal.Actors.Add(new AuditActorData() { UserIdentifier = msgEvent.ReceiveEndpoint.ToString(), UserIsRequestor = false, ActorRoleCode = new List <CodeValue>() { new CodeValue("110152", "DCM") { DisplayName = "Destination" } }, NetworkAccessPointType = NetworkAccessPointType.MachineName, NetworkAccessPointId = Dns.GetHostName(), AlternativeUserId = Process.GetCurrentProcess().Id.ToString() }); var request = msgReceiveResult.Structure as MARC.Everest.RMIM.CA.R020403.Interactions.PRPA_IN101101CA; retVal.AuditableObjects.Add(new AuditableObject() { Type = AuditableObjectType.SystemObject, Role = AuditableObjectRole.Query, IDTypeCode = AuditableObjectIdType.SearchCritereon, QueryData = Convert.ToBase64String(SerializeQuery(request.controlActEvent.QueryByParameter)), ObjectId = String.Format("{1}^^^&{0}&ISO", request.controlActEvent.QueryByParameter.QueryId.Root, request.controlActEvent.QueryByParameter.QueryId.Extension) }); break; } case "PRPA_TE101201CA": { retVal = new AuditData(DateTime.Now, action, outcome, EventIdentifierType.PatientRecord, new CodeValue(itiName, "HL7 Trigger Events")); // Audit actor for Patient Identity Source retVal.Actors.Add(new AuditActorData() { UserIsRequestor = true, UserIdentifier = msgReplyTo, ActorRoleCode = new List <CodeValue>() { new CodeValue("110153", "DCM") { DisplayName = "Source" } }, NetworkAccessPointId = msgEvent.SolicitorEndpoint.Host, NetworkAccessPointType = msgEvent.SolicitorEndpoint.HostNameType == UriHostNameType.Dns ? NetworkAccessPointType.MachineName : NetworkAccessPointType.IPAddress, UserName = userId }); // Audit actor for PIX manager retVal.Actors.Add(new AuditActorData() { UserIdentifier = msgEvent.ReceiveEndpoint.ToString(), UserIsRequestor = false, ActorRoleCode = new List <CodeValue>() { new CodeValue("110152", "DCM") { DisplayName = "Destination" } }, NetworkAccessPointType = NetworkAccessPointType.MachineName, NetworkAccessPointId = Dns.GetHostName(), AlternativeUserId = Process.GetCurrentProcess().Id.ToString() }); break; } case "PRPA_TE101105CA": { retVal = new AuditData(DateTime.Now, action, outcome, EventIdentifierType.PatientRecord, new CodeValue(itiName, "HL7 Trigger Events")); // Audit actor for Patient Identity Source retVal.Actors.Add(new AuditActorData() { UserIsRequestor = true, UserIdentifier = msgReplyTo, ActorRoleCode = new List <CodeValue>() { new CodeValue("110153", "DCM") { DisplayName = "Source" } }, NetworkAccessPointId = msgEvent.SolicitorEndpoint.Host, NetworkAccessPointType = msgEvent.SolicitorEndpoint.HostNameType == UriHostNameType.Dns ? NetworkAccessPointType.MachineName : NetworkAccessPointType.IPAddress, UserName = userId }); // Audit actor for PIX manager retVal.Actors.Add(new AuditActorData() { UserIdentifier = msgEvent.ReceiveEndpoint.ToString(), UserIsRequestor = false, ActorRoleCode = new List <CodeValue>() { new CodeValue("110152", "DCM") { DisplayName = "Destination" } }, NetworkAccessPointType = NetworkAccessPointType.MachineName, NetworkAccessPointId = Dns.GetHostName(), AlternativeUserId = Process.GetCurrentProcess().Id.ToString() }); var request = msgReceiveResult.Structure as MARC.Everest.RMIM.CA.R020403.Interactions.PRPA_IN101105CA; retVal.AuditableObjects.Add(new AuditableObject() { Type = AuditableObjectType.SystemObject, Role = AuditableObjectRole.Query, IDTypeCode = AuditableObjectIdType.SearchCritereon, QueryData = Convert.ToBase64String(SerializeQuery(request.controlActEvent.QueryByParameter)), ObjectId = String.Format("{1}^^^&{0}&ISO", request.controlActEvent.QueryByParameter.QueryId.Root, request.controlActEvent.QueryByParameter.QueryId.Extension) }); break; break; } case "ITI-44": retVal = new AuditData(DateTime.Now, action, outcome, EventIdentifierType.PatientRecord, new CodeValue(itiName, "IHE Transactions")); // Audit actor for Patient Identity Source retVal.Actors.Add(new AuditActorData() { UserIsRequestor = true, UserIdentifier = msgReplyTo, ActorRoleCode = new List <CodeValue>() { new CodeValue("110153", "DCM") { DisplayName = "Source" } }, NetworkAccessPointId = msgEvent.SolicitorEndpoint.Host, NetworkAccessPointType = msgEvent.SolicitorEndpoint.HostNameType == UriHostNameType.Dns ? NetworkAccessPointType.MachineName : NetworkAccessPointType.IPAddress, UserName = userId }); // Audit actor for PIX manager retVal.Actors.Add(new AuditActorData() { UserIdentifier = msgEvent.ReceiveEndpoint.ToString(), UserIsRequestor = false, ActorRoleCode = new List <CodeValue>() { new CodeValue("110152", "DCM") { DisplayName = "Destination" } }, NetworkAccessPointType = NetworkAccessPointType.MachineName, NetworkAccessPointId = Dns.GetHostName(), AlternativeUserId = Process.GetCurrentProcess().Id.ToString() }); break; case "ITI-45": { retVal = new AuditData(DateTime.Now, ActionType.Execute, outcome, EventIdentifierType.Query, new CodeValue("ITI-45", "IHE Transactions") { DisplayName = "PIX Query" }); // Audit actor for Patient Identity Source retVal.Actors.Add(new AuditActorData() { UserIsRequestor = true, UserIdentifier = msgReplyTo, ActorRoleCode = new List <CodeValue>() { new CodeValue("110153", "DCM") { DisplayName = "Source" } }, NetworkAccessPointId = msgEvent.SolicitorEndpoint.Host, NetworkAccessPointType = msgEvent.SolicitorEndpoint.HostNameType == UriHostNameType.Dns ? NetworkAccessPointType.MachineName : NetworkAccessPointType.IPAddress, UserName = userId }); // Audit actor for PIX manager retVal.Actors.Add(new AuditActorData() { UserIdentifier = msgEvent.ReceiveEndpoint.ToString(), UserIsRequestor = false, ActorRoleCode = new List <CodeValue>() { new CodeValue("110152", "DCM") { DisplayName = "Destination" } }, NetworkAccessPointType = NetworkAccessPointType.MachineName, NetworkAccessPointId = Dns.GetHostName(), AlternativeUserId = Process.GetCurrentProcess().Id.ToString() }); // Add query var request = msgReceiveResult.Structure as PRPA_IN201309UV02; retVal.AuditableObjects.Add(new AuditableObject() { Type = AuditableObjectType.SystemObject, Role = AuditableObjectRole.Query, IDTypeCode = AuditableObjectIdType.Custom, CustomIdTypeCode = new CodeValue("ITI45", "IHE Transactions"), QueryData = Convert.ToBase64String(SerializeQuery(request.controlActProcess.queryByParameter)), ObjectId = String.Format("{1}^^^&{0}&ISO", request.controlActProcess.queryByParameter.QueryId.Root, request.controlActProcess.queryByParameter.QueryId.Extension) }); break; } case "ITI-47": { retVal = new AuditData(DateTime.Now, ActionType.Execute, outcome, EventIdentifierType.Query, new CodeValue("ITI-47", "IHE Transactions") { DisplayName = "Patient Demographics Query" }); // Audit actor for Patient Identity Source retVal.Actors.Add(new AuditActorData() { UserIsRequestor = true, UserIdentifier = msgReplyTo, ActorRoleCode = new List <CodeValue>() { new CodeValue("110153", "DCM") { DisplayName = "Source" } }, NetworkAccessPointId = msgEvent.SolicitorEndpoint.Host, NetworkAccessPointType = msgEvent.SolicitorEndpoint.HostNameType == UriHostNameType.Dns ? NetworkAccessPointType.MachineName : NetworkAccessPointType.IPAddress, UserName = userId }); // Audit actor for PIX manager retVal.Actors.Add(new AuditActorData() { UserIdentifier = msgEvent.ReceiveEndpoint.ToString(), UserIsRequestor = false, ActorRoleCode = new List <CodeValue>() { new CodeValue("110152", "DCM") { DisplayName = "Destination" } }, NetworkAccessPointType = NetworkAccessPointType.MachineName, NetworkAccessPointId = Dns.GetHostName(), AlternativeUserId = Process.GetCurrentProcess().Id.ToString() }); // Add query var request = msgReceiveResult.Structure as PRPA_IN201305UV02; retVal.AuditableObjects.Add(new AuditableObject() { Type = AuditableObjectType.SystemObject, Role = AuditableObjectRole.Query, IDTypeCode = AuditableObjectIdType.Custom, CustomIdTypeCode = new CodeValue("ITI47", "IHE Transactions"), QueryData = Convert.ToBase64String(SerializeQuery(request.controlActProcess.queryByParameter)), ObjectId = String.Format("{1}^^^&{0}&ISO", request.controlActProcess.queryByParameter.QueryId.Root, request.controlActProcess.queryByParameter.QueryId.Extension) }); break; } } // Audit authors if (author != null) { retVal.AuditableObjects.Add(new AuditableObject() { IDTypeCode = AuditableObjectIdType.UserIdentifier, ObjectId = String.Format("{1}^^^&{0}&ISO", this.m_configService.OidRegistrar.GetOid("CR_PID"), author.Id), Role = AuditableObjectRole.Provider, Type = AuditableObjectType.Person, LifecycleType = (AuditableObjectLifecycle?)(action == ActionType.Read ? (object)AuditableObjectLifecycle.ReceiptOfDisclosure : null) }); } // Audit patients foreach (var pat in patientRecord) { // Construct the audit object AuditableObject aud = new AuditableObject() { IDTypeCode = AuditableObjectIdType.PatientNumber, Role = AuditableObjectRole.Patient, Type = AuditableObjectType.Person }; // Lifecycle switch (action) { case ActionType.Create: aud.LifecycleType = AuditableObjectLifecycle.Creation; break; case ActionType.Delete: aud.LifecycleType = AuditableObjectLifecycle.LogicalDeletion; break; case ActionType.Execute: aud.LifecycleType = AuditableObjectLifecycle.Access; break; case ActionType.Read: aud.LifecycleType = AuditableObjectLifecycle.Disclosure; break; case ActionType.Update: aud.LifecycleType = AuditableObjectLifecycle.Amendment; break; } aud.ObjectId = String.Format("{1}^^^&{0}&ISO", pat.Domain, pat.Identifier); retVal.AuditableObjects.Add(aud); } return(retVal); }
/// <summary> /// Create audit data that is in response to a query /// </summary> internal AuditData CreateAuditData(string itiName, ActionType actionType, OutcomeIndicator outcomeIndicator, UnsolicitedDataEventArgs msgEvent, IReceiveResult msgReceiveResult, RegistryQueryResult result, HealthcareParticipant author) { // Create the call to the other create audit data message by constructing the list of disclosed identifiers List <VersionedDomainIdentifier> vids = new List <VersionedDomainIdentifier>(result.Results.Count); foreach (var res in result.Results) { if (res == null) { continue; } var subj = res.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person; if (subj == null) { continue; } vids.Add(new VersionedDomainIdentifier() { Domain = this.m_configService.OidRegistrar.GetOid("CR_CID").Oid, Identifier = subj.Id.ToString() }); } return(CreateAuditData(itiName, actionType, outcomeIndicator, msgEvent, msgReceiveResult, vids, author)); }