Exemplo n.º 1
0
        /// <summary>
        /// Validate the message
        /// </summary>
        internal static void Validate(IMessage message, ISystemConfigurationService config, List <IResultDetail> dtls, IServiceProvider context)
        {
            // Structure validation
            PipeParser pp = new PipeParser()
            {
                ValidationContext = new DefaultValidation()
            };

            try
            {
                pp.Encode(message);
            }
            catch (Exception e)
            {
                dtls.Add(new ValidationResultDetail(ResultDetailType.Error, e.Message, e));
            }

            // Validation of sending application
            try
            {
                Terser msgTerser = new Terser(message);
                object obj       = msgTerser.getSegment("MSH") as NHapi.Model.V25.Segment.MSH;
                if (obj != null)
                {
                    var msh      = obj as NHapi.Model.V25.Segment.MSH;
                    var domainId = new ComponentUtility()
                    {
                        Context = context
                    }.CreateDomainIdentifier(msh.SendingApplication, dtls);
                    if (!config.IsRegisteredDevice(domainId))
                    {
                        dtls.Add(new UnrecognizedSenderResultDetail(domainId));
                    }
                }
                else
                {
                    obj = msgTerser.getSegment("MSH") as NHapi.Model.V231.Segment.MSH;
                    if (obj != null)
                    {
                        var msh      = obj as NHapi.Model.V231.Segment.MSH;
                        var domainId = new ComponentUtility()
                        {
                            Context = context
                        }.CreateDomainIdentifier(msh.SendingApplication, dtls);
                        if (!config.IsRegisteredDevice(domainId))
                        {
                            dtls.Add(new UnrecognizedSenderResultDetail(domainId));
                        }
                    }
                    else
                    {
                        dtls.Add(new MandatoryElementMissingResultDetail(ResultDetailType.Error, "Missing MSH", "MSH"));
                    }
                }
            }
            catch (Exception e)
            {
                dtls.Add(new ResultDetail(ResultDetailType.Error, e.Message, e));
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Create NACK
        /// </summary>
        internal static IMessage CreateNack(IMessage request, List <IResultDetail> errors, IServiceProvider context, Type errType)
        {
            var config = context.GetService(typeof(ISystemConfigurationService)) as ISystemConfigurationService;

            IMessage ack = errType.GetConstructor(Type.EmptyTypes).Invoke(null) as IMessage;

            Trace.TraceError("Validation Errors:");
            errors.ForEach(o => Trace.TraceError("\t{0} : {1}", o.Type, o.Message));

            Terser terser = new Terser(ack);

            MessageUtil.UpdateMSH(terser, request, config);
            int errLevel = 0;

            int ec = 0;

            foreach (var dtl in errors)
            {
                try
                {
                    ISegment errSeg;
                    if (ack.Version == "2.5")
                    {
                        errSeg = terser.getSegment(String.Format("/ERR({0})", ec++));
                    }
                    else
                    {
                        errSeg = terser.getSegment(String.Format("/ERR", ec++));
                    }

                    if (errSeg is NHapi.Model.V231.Segment.ERR)
                    {
                        var tErr = MessageUtil.UpdateERR(errSeg as NHapi.Model.V231.Segment.ERR, dtl, context);
                        if (tErr > errLevel)
                        {
                            errLevel = tErr;
                        }
                    }
                    else if (errSeg is NHapi.Model.V25.Segment.ERR)
                    {
                        var tErr = MessageUtil.UpdateERR(errSeg as NHapi.Model.V25.Segment.ERR, dtl, context);
                        if (tErr > errLevel)
                        {
                            errLevel = tErr;
                        }
                    }
                }
                catch (Exception e)
                {
                    Trace.TraceError(e.ToString());
                }
            }

            terser.Set("/MSA-1", errLevel == 0 ? "AA" : errLevel == 1 ? "AE" : "AR");

            return(ack);
        }
Exemplo n.º 3
0
 /// <summary>
 /// Create a new instance of HL7Message
 /// </summary>
 /// <param name="message"></param>
 public HL7Message(IMessage message)
 {
     this.m_Message   = message;
     this.m_HL7Parser = new HL7Parser();
     this.m_Terser    = new Terser(m_Message);
     this.m_MSH       = m_Terser.getSegment("MSH");
 }
Exemplo n.º 4
0
        private void SetACK(AckTypes ackType, String messageString)
        {
            Terser   terser          = new Terser(hl7Ack.Message);
            ISegment err             = terser.getSegment("/ERR(0)");
            ISegment criticalSegment = TryToRecoverCriticalDataFromMessage(messageString);


            try
            {
                FillMSHSegment((ISegment)hl7Ack.Message.GetStructure("MSH"), criticalSegment);

                if (criticalSegment == null)
                {
                    terser.Set("/MSA-1", Enum.GetName(typeof(AckTypes), ackType));
                    terser.Set("/MSA-2", "");
                }
                else
                {
                    terser.Set("/MSA-1", Enum.GetName(typeof(AckTypes), ackType));
                    terser.Set("/MSA-2", Terser.Get(criticalSegment, 10, 0, 1, 1));
                }
            }
            catch (HL7Exception he)
            {
                _errorMessage.Append(he.Message);
                return; //do not throw exceptions;
            }
            //terser.Set("ERR(0)-7", _errorMessage);
            terser.Set("/ERR(0)-7-1-1", _errorMessage.ToString());
        }
Exemplo n.º 5
0
        /// <summary>
        /// Create an Ack message based on a received message
        /// </summary>
        /// <param name="inboundMessage">received message</param>
        /// <param name="ackCode">Should be "AE" or "AR", can be "AA".</param>
        /// <param name="errorMessage">The reason the message was rejected or an error. If "AA" was supplied as ackCode the errorMessage should be null.</param>
        /// <returns>Created ACK message</returns>
        public static IMessage MakeACK(IMessage inboundMessage, string ackCode, string errorMessage)
        {
            IMessage ackMessage = null;
            // Get an object from the right ACK class
            string ackClassType = string.Format("NHapi.Model.V{0}.Message.ACK, NHapi.Model.V{0}", inboundMessage.Version.Remove(inboundMessage.Version.IndexOf('.'), 1));
            Type   x            = Type.GetType(ackClassType);

            ackMessage = (IMessage)Activator.CreateInstance(x);

            Terser   inboundTerser = new Terser(inboundMessage);
            ISegment inboundHeader = null;

            inboundHeader = inboundTerser.getSegment("MSH");

            // Find the HL7 version of the inbound message:
            //
            string version = null;

            try
            {
                version = Terser.Get(inboundHeader, 12, 0, 1, 1);
            }
            catch (NHapi.Base.HL7Exception)
            {
                // I'm not happy to proceed if we can't identify the inbound
                // message version.
                throw new NHapi.Base.HL7Exception("Failed to get valid HL7 version from inbound MSH-12-1");
            }

            // Create a Terser instance for the outbound message (the ACK).
            Terser terser = new Terser(ackMessage);

            // Populate outbound MSH fields using data from inbound message
            ISegment outHeader = (ISegment)terser.getSegment("MSH");

            DeepCopy.copy(inboundHeader, outHeader);

            // Now set the message type, HL7 version number, acknowledgement code
            // and message control ID fields:
            string sendingApp = terser.Get("/MSH-3");
            string sendingEnv = terser.Get("/MSH-4");

            terser.Set("/MSH-3", CommunicationName);
            terser.Set("/MSH-4", EnvironmentIdentifier);
            terser.Set("/MSH-5", sendingApp);
            terser.Set("/MSH-6", sendingEnv);
            terser.Set("/MSH-7", DateTime.Now.ToString("yyyyMMddmmhh"));
            terser.Set("/MSH-9", "ACK");
            terser.Set("/MSH-12", version);
            terser.Set("/MSA-1", ackCode == null ? "AA" : ackCode);
            terser.Set("/MSA-2", Terser.Get(inboundHeader, 10, 0, 1, 1));

            // Set error message
            if (errorMessage != null)
            {
                terser.Set("/ERR-7", errorMessage);
            }

            return(ackMessage);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Validates a message.
        /// </summary>
        /// <param name="message">The message to be validated.</param>
        /// <param name="details">The result details for storing the message validation results.</param>
        /// <returns>Returns a list of validation results.</returns>
        public static List <IResultDetail> Validate(IMessage message, List <IResultDetail> details)
        {
            var pipeParser = new PipeParser()
            {
                ValidationContext = new DefaultValidation()
            };

            try
            {
                pipeParser.Encode(message);
            }
            catch (Exception e)
            {
                details.Add(new ValidationResultDetail(ResultDetailType.Error, e.Message, e));
            }

            try
            {
                var terser = new Terser(message);

                var msh = terser.getSegment("MSH");

                if (msh is MSH)
                {
                    var v231Msh = (MSH)msh;

                    var result = ConvertAssigningAuthority(v231Msh.SendingApplication, details);

                    if (result == null)
                    {
                        details.Add(new UnrecognizedSenderResultDetail(ResultDetailType.Error, v231Msh.SendingApplication.NamespaceID.Value, "MSH^3"));
                    }
                }
                else if (msh is NHapi.Model.V25.Segment.MSH)
                {
                    var v25Msh = (NHapi.Model.V25.Segment.MSH)msh;

                    var result = ConvertAssigningAuthority(v25Msh.SendingApplication, details);

                    if (result == null)
                    {
                        details.Add(new UnrecognizedSenderResultDetail(ResultDetailType.Error, v25Msh.SendingApplication.NamespaceID.Value, "MSH^3"));
                    }
                }
                else
                {
                    details.Add(new MandatoryElementMissingResultDetail(ResultDetailType.Error, "Missing MSH", "MSH"));
                }
            }
            catch (Exception e)
            {
                details.Add(new ResultDetail(ResultDetailType.Error, e.Message, e));
            }

            return(details);
        }
Exemplo n.º 7
0
        public static void MakeACK(ISegment inboundHeader, string ackCode, IMessage ackMessage, string errorMessage)
        {
            if (!inboundHeader.GetStructureName().Equals("MSH"))
            {
                throw new NHapi.Base.HL7Exception("Need an MSH segment to create a response ACK (got " + inboundHeader.GetStructureName() + ")");
            }

            // Find the HL7 version of the inbound message:
            string version = null;

            try
            {
                version = Terser.Get(inboundHeader, 12, 0, 1, 1);
            }
            catch (NHapi.Base.HL7Exception)
            {
                // I'm not happy to proceed if we can't identify the inbound
                // message version.
                throw new NHapi.Base.HL7Exception("Failed to get valid HL7 version from inbound MSH-12-1");
            }

            // Create a Terser instance for the outbound message (the ACK).
            Terser terser = new Terser(ackMessage);

            // Populate outbound MSH fields using data from inbound message
            ISegment outHeader = (ISegment)terser.getSegment("MSH");

            DeepCopy.copy(inboundHeader, outHeader);

            // Now set the message type, HL7 version number, acknowledgement code
            // and message control ID fields:
            string sendingApp = terser.Get("/MSH-3");
            string sendingEnv = terser.Get("/MSH-4");

            // Make sure you fill the MSH-3 and MSH-4 with the correct values
            // for you application, preferably with configuration
            terser.Set("/MSH-3", "HL7Client");
            terser.Set("/MSH-4", "EnvironmentIdentifier");
            terser.Set("/MSH-5", sendingApp);
            terser.Set("/MSH-6", sendingEnv);
            terser.Set("/MSH-7", DateTime.Now.ToString("yyyyMMddmmhh"));
            terser.Set("/MSH-9", "ACK");
            terser.Set("/MSH-12", version);
            terser.Set("/MSA-1", ackCode == null ? "AA" : ackCode);
            terser.Set("/MSA-2", Terser.Get(inboundHeader, 10, 0, 1, 1));

            // Set error message
            if (errorMessage != null)
            {
                terser.Set("/ERR-7", errorMessage);
            }
        }
        public static IMessage MakeACK(ISegment inboundHeader, string ackCode)
        {
            if (!inboundHeader.GetStructureName().Equals("MSH"))
            {
                throw new NHapi.Base.HL7Exception(
                          "Need an MSH segment to create a response ACK (got " + inboundHeader.GetStructureName() + ")");
            }

            // Find the HL7 version of the inbound message:
            //
            string version = null;

            try
            {
                version = Terser.Get(inboundHeader, 12, 0, 1, 1);
            }
            catch (NHapi.Base.HL7Exception)
            {
                // I'm not happy to proceed if we can't identify the inbound
                // message version.
                throw new NHapi.Base.HL7Exception("Failed to get valid HL7 version from inbound MSH-12-1");
            }

            IMessage ackMessage = new ACK();
            // Create a Terser instance for the outbound message (the ACK).
            Terser terser = new Terser(ackMessage);

            // Populate outbound MSH fields using data from inbound message
            ISegment outHeader = (ISegment)terser.getSegment("MSH");

            DeepCopy.copy(inboundHeader, outHeader);

            // Now set the message type, HL7 version number, acknowledgement code
            // and message control ID fields:
            string sendingApp = terser.Get("/MSH-3");
            string sendingEnv = terser.Get("/MSH-4");

            terser.Set("/MSH-3", CommunicationName);
            terser.Set("/MSH-4", EnvironmentIdentifier);
            terser.Set("/MSH-5", sendingApp);
            terser.Set("/MSH-6", sendingEnv);
            terser.Set("/MSH-7", DateTime.Now.ToString("yyyyMMddmmhh"));
            terser.Set("/MSH-9", "ACK");
            terser.Set("/MSH-12", version);
            terser.Set("/MSA-1", ackCode == null ? "AA" : ackCode);
            terser.Set("/MSA-2", Terser.Get(inboundHeader, 10, 0, 1, 1));

            return(ackMessage);
        }
        public static IMessage MakeACK(IMessage inboundMessage, string ackCode)
        {
            Terser   t             = new Terser(inboundMessage);
            ISegment inboundHeader = null;

            try
            {
                inboundHeader = t.getSegment("MSH");
            }
            catch (NHapi.Base.HL7Exception)
            {
                throw new NHapi.Base.HL7Exception("Need an MSH segment to create a response ACK");
            }
            return(MakeACK(inboundHeader, ackCode));
        }
Exemplo n.º 10
0
        internal void SetACK(AckTypes ackType, String messageString, IMessage message)
        {
            if (message == null)
            {
                SetACK(ackType, messageString);
                return;
            }
            Terser   inboundTerser = new Terser(message);
            ISegment inboundHeader = inboundTerser.getSegment("MSH");

            string version = null;

            version = message.Version;
            if (string.IsNullOrEmpty(version))
            {
                try
                {
                    version = Terser.Get(inboundHeader, 12, 0, 1, 1);
                }
                catch (NHapi.Base.HL7Exception he)
                {
                    version = NHapi.Model.V251.Constants.VERSION;
                }
            }

            FillMSHSegment((ISegment)message.GetStructure("MSH"), (ISegment)hl7Ack.Message.GetStructure("MSH"));


            string messageTypeName = message.GetMessageType();
            string acktype         = HL7Parser.GetAckTypeFromRequest(messageTypeName, version);
            string AckID           = HL7Parser.GetMessageIDFromMessageType(acktype, version);

            hl7Ack.SetValue("/MSH(0)-21-1", AckID); //MEssage Code

            if (acktype.Split('_').Length > 1)
            {
                hl7Ack.SetValue("/MSH-9-1-1", acktype.Split('_')[0]); //MEssage Code
                hl7Ack.SetValue("/MSH-9-2-1", acktype.Split('_')[1]); //MEssage Code
            }
            //ackTerser.Set("/MSH-12", NHapi.Model.V251.Constants.VERSION);
            hl7Ack.SetValue("/MSA-1", Enum.GetName(typeof(AckTypes), ackType));

            string code = Terser.Get(inboundHeader, 10, 0, 1, 1);

            hl7Ack.SetValue("/MSA-2", Terser.Get(inboundHeader, 10, 0, 1, 1));
        }
Exemplo n.º 11
0
        /// <summary>
        /// Create an Ack message based on a received message
        /// </summary>
        /// <param name="inboundMessage">received message</param>
        /// <param name="ackResult">Send AA, AE or AR message.</param>
        /// <param name="errorMessage">The reason the message was rejected or an error. If "AA" was supplied as ackCode the errorMessage should be null.</param>
        /// <returns>Created ACK message</returns>
        public IMessage MakeACK(IMessage inboundMessage, AckTypes ackResult, string errorMessage)
        {
            //this should avoid an unhandled null reference exception in "inboundMessage.Version", because people tend to send the inboudMessage without a check
            if (inboundMessage == null)
            {
                throw new ArgumentNullException("Either process the valid message while retreiving the ack or handle invalid message differently");
            }

            IMessage ackMessage = null;
            // Get an object from the right ACK class
            string ackClassType = string.Format("NHapi.Model.V{0}.Message.ACK, NHapi.Model.V{0}", inboundMessage.Version.Replace(".", ""));
            Type   x            = Type.GetType(ackClassType);

            if (x != null)
            {
                ackMessage = (IMessage)Activator.CreateInstance(x);
            }
            else
            {
                // Fix for V2.2 and V2.1 Since tha ACK message class is missing there in NHapi
                if (inboundMessage.Version == "2.1")
                {
                    ackMessage = (IMessage) new NHapiTools.Base.CustomImplementation.V21.Messages.ACK();
                }
                if (inboundMessage.Version == "2.2")
                {
                    ackMessage = (IMessage) new NHapiTools.Base.CustomImplementation.V22.Messages.ACK();
                }
            }

            Terser   inboundTerser = new Terser(inboundMessage);
            ISegment inboundHeader = null;

            inboundHeader = inboundTerser.getSegment("MSH");

            // Find the HL7 version of the inbound message:
            string version = null;

            try
            {
                version = Terser.Get(inboundHeader, 12, 0, 1, 1);
            }
            catch (NHapi.Base.HL7Exception)
            {
                // I'm not happy to proceed if we can't identify the inbound
                // message version.
                throw new NHapi.Base.HL7Exception("Failed to get valid HL7 version from inbound MSH-12-1");
            }

            // Create a Terser instance for the outbound message (the ACK).
            Terser terser = new Terser(ackMessage);

            // Populate outbound MSH fields using data from inbound message
            ISegment outHeader = (ISegment)terser.getSegment("MSH");

            DeepCopy.copy(inboundHeader, outHeader);

            // Now set the message type, HL7 version number, acknowledgement code
            // and message control ID fields:
            string sendingApp = terser.Get("/MSH-3");
            string sendingEnv = terser.Get("/MSH-4");

            terser.Set("/MSH-3", appCommunicationName);
            terser.Set("/MSH-4", environmentIdentifier);
            terser.Set("/MSH-5", sendingApp);
            terser.Set("/MSH-6", sendingEnv);
            terser.Set("/MSH-7", DateTime.Now.ToString("yyyyMMddmmhh"));
            terser.Set("/MSH-9", "ACK");
            terser.Set("/MSH-9-3", "ACK");
            terser.Set("/MSH-12", version);
            terser.Set("/MSA-1", Enum.GetName(typeof(AckTypes), ackResult));
            terser.Set("/MSA-2", Terser.Get(inboundHeader, 10, 0, 1, 1));

            // Set error message
            if (errorMessage != null)
            {
                terser.Set("/ERR-1-1", errorMessage);
            }

            return(ackMessage);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Creates a negative acknowledgement message.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="errors">The errors.</param>
        /// <param name="errType">Type of the error.</param>
        /// <returns>Returns the created negative acknowledgement message instance.</returns>
        public static IMessage CreateNack(IMessage request, List <IResultDetail> errors, Type errType)
        {
            var ack = errType.GetConstructor(Type.EmptyTypes).Invoke(null) as IMessage;

            if (errors.Any())
            {
                tracer.TraceEvent(TraceEventType.Warning, 0, "Validation Errors:");

                errors.ForEach(o => tracer.TraceEvent(TraceEventType.Error, 0, $"\t{o.Type} : {o.Message}"));
            }

            var terser = new Terser(ack);

            MessageUtil.UpdateMSH(terser, request);

            var errLevel = 0;

            var ec = 0;

            foreach (var dtl in errors)
            {
                try
                {
                    ISegment errSeg;
                    if (ack.Version == "2.5")
                    {
                        errSeg = terser.getSegment($"/ERR({ec++})");
                    }
                    else
                    {
                        errSeg = terser.getSegment(string.Format("/ERR", ec++));
                    }

                    if (errSeg is ERR)
                    {
                        var tErr = UpdateERR(errSeg as ERR, dtl);

                        if (tErr > errLevel)
                        {
                            errLevel = tErr;
                        }
                    }
                    else if (errSeg is NHapi.Model.V25.Segment.ERR)
                    {
                        var tErr = UpdateERR(errSeg as ERR, dtl);

                        if (tErr > errLevel)
                        {
                            errLevel = tErr;
                        }
                    }
                }
                catch (Exception e)
                {
                    Trace.TraceError(e.ToString());
                }
            }

            terser.Set("/MSA-1", errLevel == 0 ? "AA" : errLevel == 1 ? "AE" : "AR");

            return(ack);
        }