Example #1
0
        /// <summary>
        /// Transport has received a message!
        /// </summary>
        private void m_transport_MessageReceived(object sender, Hl7MessageReceivedEventArgs e)
        {
            IMessagePersistenceService messagePersister = ApplicationServiceContext.Current.GetService(typeof(IMessagePersistenceService)) as IMessagePersistenceService;

            // Find the message that supports the type
            Terser msgTerser   = new Terser(e.Message);
            string messageType = String.Format("{0}^{1}", msgTerser.Get("/MSH-9-1"), msgTerser.Get("/MSH-9-2"));
            string messageId   = msgTerser.Get("/MSH-10");

            // Find a handler
            HandlerDefinition handler        = m_serviceDefinition.MessageHandlers.Find(o => o.Types.Exists(a => a.Name == messageType)),
                              defaultHandler = m_serviceDefinition.MessageHandlers.Find(o => o.Types.Exists(a => a.Name == "*"));

            if (handler != null && handler.Types.Find(o => o.Name == messageType).IsQuery ||
                defaultHandler != null && defaultHandler.Types.Find(o => o.Name == "*").IsQuery)
            {
                messagePersister = null;
            }

            // Have we already processed this message?
            MessageState msgState = MessageState.New;

            if (messagePersister != null)
            {
                msgState = messagePersister.GetMessageState(messageId);
            }

            switch (msgState)
            {
            case MessageState.New:

                if (messagePersister != null)
                {
                    messagePersister.PersistMessage(messageId, CreateMessageStream(e.Message));
                }

                if (handler == null && defaultHandler == null)
                {
                    throw new InvalidOperationException(String.Format("Cannot find message handler for '{0}'", messageType));
                }

                e.Response = (handler ?? defaultHandler).Handler.HandleMessage(e);
                if (e.Response == null)
                {
                    throw new InvalidOperationException("Couldn't process message");
                }

                msgTerser = new Terser(e.Response);
                if (messagePersister != null)
                {
                    messagePersister.PersistResultMessage(msgTerser.Get("/MSH-10"), messageId, CreateMessageStream(e.Response));
                }
                break;

            case MessageState.Active:
                throw new InvalidOperationException("Message already in progress");

            case MessageState.Complete:
                NHapi.Base.Parser.PipeParser pp = new NHapi.Base.Parser.PipeParser();
                using (var rdr = new StreamReader(messagePersister.GetMessageResponseMessage(messageId)))
                    e.Response = pp.Parse(rdr.ReadToEnd());
                break;
            }
        }
Example #2
0
        /// <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;
            }
        }