예제 #1
0
        /**
         * Construct an EbXmlMessage for sending.
         *
         * @param s An SdSTransmissionDetails instance for recipient information
         * @param m SpineHL7Message instance to be sent
         * @param c Reference to an SDSconnection for resolving URLs
         */
        public EbXmlMessage(SdsTransmissionDetails s, SpineHL7Message m)
        {
            SDSconnection c = ConnectionManager.getInstance().SdsConnection;

            odsCode    = s.Org;
            header     = new EbXmlHeader(this, s);
            type       = EBXML;
            hl7message = m;
            string svcurl = c.resolveUrl(s.SvcIA);

            if (svcurl == null)
            {
                resolvedUrl = s.Url;
            }
            else
            {
                resolvedUrl = svcurl;
            }
            if (s.Retries != SdsTransmissionDetails.NOT_SET)
            {
                retryCount       = s.Retries;
                minRetryInterval = s.RetryInterval;
                persistDuration  = s.PersistDuration;
            }
            attachments = new List <Attachment>();
            persistable = (s.Retries > 0);
        }
        /**
         * Construct a SpineSOAPRequest for sending.
         *
         * @param s An SdSTransmissionDetails instance for recipient information
         * @param m SpineHL7Message instance to be sent
         * @param c Reference to an SDSconnection for resolving URLs
         */
        public SpineSOAPRequest(SdsTransmissionDetails s, SpineHL7Message m)
        {
            if (bootException != null)
                throw bootException;
            SDSconnection c = ConnectionManager.getInstance().SdsConnection;
            type = Sendable.SOAP;
            myAsid = c.MyAsid;
            messageid = Guid.NewGuid().ToString().ToUpper();
            lock (messageid)
            {
                if (myIp == null)
                {
                    ConnectionManager cm = ConnectionManager.getInstance();
                    if (cm.MyIp == null)
                    {
                        try
                        {
                            IPAddress[] addresses = Dns.GetHostAddresses("");
                            myIp = addresses[0].ToString();
                        }
                        catch (Exception e)
                        {
                            bootException = e;
                            throw e;
                        }
                        if (myIp == null)
                        {
                            bootException = new Exception("No non-localhost IP interfaces found");
                            throw bootException;
                        }
                    }
                    else
                    {
                        myIp = cm.MyIp;
                    }
                }
                if (template == null)
                {
                    Assembly assembly = Assembly.GetExecutingAssembly();
                    StreamReader sr = new StreamReader(assembly.GetManifestResourceStream(SOAPREQUESTTEMPLATE));
                    StringBuilder sb = new StringBuilder();
                    try
                    {
                        String line = null;
                        while ((line = sr.ReadLine()) != null)
                        {
                            sb.Append(line);
                            sb.Append("\r\n");
                        }
                        template = sb.ToString();
                    }
                    catch (Exception e)
                    {
                        bootException = e;
                        throw e;
                    }

                }
            }
            transmissionDetails = s;
            hl7Message = m;
            string svcurl = c.resolveUrl(s.SvcIA);
            if (svcurl == null)
                resolvedUrl = s.Url;
            else
                resolvedUrl = svcurl;
        }
        static void Main(string[] args)
        {
            ConnectionManager cm = ConnectionManager.getInstance();
            SDSconnection c = cm.SdsConnection;
            cm.listen();
               // cm.loadPersistedMessages();

            //           List<SdsTransmissionDetails> sdsdetails = c.getTransmissionDetails("urn:nhs:names:services:pdsquery:QUPA_IN000008UK02", "YES", null, null);
            // /            List<SdsTransmissionDetails> sdsdetails = c.getTransmissionDetails("urn:nhs:names:services:pdsquery:QUPA_IN020000UK31", "YEA", "631955299542", null);
            //            List<SdsTransmissionDetails> sdsdetails = c.getTransmissionDetails("urn:nhs:names:services:mm:PORX_IN020101UK31", "YEA", "631955299542", null);
              /*          string qstring = null;
            using (StreamReader rdr = File.OpenText(@"c:\test\data\query.txt"))
            {
                qstring = rdr.ReadToEnd();
            }
            // SpineHL7Message msg = new SpineHL7Message("QUPA_IN020000UK31", qstring);
            //SpineHL7Message msg = new SpineHL7Message("PORX_IN020101UK31", qstring);
            SpineHL7Message msg = new SpineHL7Message("QUPA_IN000008UK02", qstring);
            SpineSOAPRequest req = new SpineSOAPRequest(sdsdetails[0], msg);
            msg.ToAsid = sdsdetails[0].Asid[0];
            msg.MyAsid = c.MyAsid;
            msg.IsQuery = true;
            //EbXmlMessage eb = new EbXmlMessage(sdsdetails[0], msg, c);

            MemoryStream ms = new MemoryStream();
             req.write(ms);
            //eb.write(ms);
            ms.Seek(0, SeekOrigin.Begin);
            StreamReader sr = new StreamReader(ms);
            string s = sr.ReadToEnd();

            cm.send(req, sdsdetails[0]);
            */
            //cm.listen();
            //            while (true) ;

            //            List<SdsTransmissionDetails> sdsdetails = c.getTransmissionDetails("urn:nhs:names:services:pdsquery:QUPA_IN000008UK02", "YES", null, null);
            //            List<SdsTransmissionDetails> sdsdetails = c.getTransmissionDetails("urn:nhs:names:services:pdsquery:QUPA_IN040000UK32", "YES", null, null);
            //            List<SdsTransmissionDetails> sdsdetails = c.getTransmissionDetails("urn:nhs:names:services:mm:PORX_IN132004UK30", "YES", null, null);
            List<SdsTransmissionDetails> sdsdetails = c.getTransmissionDetails("urn:nhs:names:services:psis:REPC_IN150015UK05", "YES", null, null);

            //            List<SdsTransmissionDetails> sdsdetails = c.getTransmissionDetails("urn:nhs:names:services:pdsquery:QUPA_IN000006UK02", "YES", null, null);
            int i = sdsdetails.Count;
            cm.listen();
            string qstring = null;
            using (StreamReader rdr = File.OpenText(@"c:\test\data\REPC_IN150015UK05_mhstest.xml"))
            {
                qstring = rdr.ReadToEnd();
            }
            SpineHL7Message msg = new SpineHL7Message("REPC_IN150015UK05", qstring);
            msg.ToAsid = sdsdetails[0].Asid[0];
            msg.MyAsid = c.MyAsid;
            msg.AuthorRole = "S0080:G0450:R5080";
            msg.AuthorUid = "687227875014";
            msg.AuthorUrp = "012345678901";

            EbXmlMessage eb = new EbXmlMessage(sdsdetails[0], msg);
            //          eb.Attachments.Add(deattachment);
                        MemoryStream ms = new MemoryStream();
                        eb.write(ms);
                        ms.Seek(0, SeekOrigin.Begin);
                        StreamReader sr = new StreamReader(ms);
                        string s = sr.ReadToEnd();
                   cm.send(eb, sdsdetails[0]);
        }
예제 #4
0
        /**
         * Construct a SpineSOAPRequest for sending.
         *
         * @param s An SdSTransmissionDetails instance for recipient information
         * @param m SpineHL7Message instance to be sent
         * @param c Reference to an SDSconnection for resolving URLs
         */
        public SpineSOAPRequest(SdsTransmissionDetails s, SpineHL7Message m)
        {
            if (bootException != null)
            {
                throw bootException;
            }
            SDSconnection c = ConnectionManager.getInstance().SdsConnection;

            type      = Sendable.SOAP;
            myAsid    = c.MyAsid;
            messageid = Guid.NewGuid().ToString().ToUpper();
            lock (messageid)
            {
                if (myIp == null)
                {
                    ConnectionManager cm = ConnectionManager.getInstance();
                    if (cm.MyIp == null)
                    {
                        try
                        {
                            IPAddress[] addresses = Dns.GetHostAddresses("");
                            myIp = addresses[0].ToString();
                        }
                        catch (Exception e)
                        {
                            bootException = e;
                            throw e;
                        }
                        if (myIp == null)
                        {
                            bootException = new Exception("No non-localhost IP interfaces found");
                            throw bootException;
                        }
                    }
                    else
                    {
                        myIp = cm.MyIp;
                    }
                }
                if (template == null)
                {
                    Assembly      assembly = Assembly.GetExecutingAssembly();
                    StreamReader  sr       = new StreamReader(assembly.GetManifestResourceStream(SOAPREQUESTTEMPLATE));
                    StringBuilder sb       = new StringBuilder();
                    try
                    {
                        String line = null;
                        while ((line = sr.ReadLine()) != null)
                        {
                            sb.Append(line);
                            sb.Append("\r\n");
                        }
                        template = sb.ToString();
                    }
                    catch (Exception e)
                    {
                        bootException = e;
                        throw e;
                    }
                }
            }
            transmissionDetails = s;
            hl7Message          = m;
            string svcurl = c.resolveUrl(s.SvcIA);

            if (svcurl == null)
            {
                resolvedUrl = s.Url;
            }
            else
            {
                resolvedUrl = svcurl;
            }
        }
예제 #5
0
        /**
         * Used to assemble an EbXmlMessage from the given Stream, which has been accepted from the network.
         * This expects to get the inbound HTTP stream (or at least an SslStream) from the start, because it
         * begins processing with the HTTP POST.
         */
        public EbXmlMessage(Stream instream)
        {
            // Assemble from network - note that Spine messages are NOT chunked
            //
            string headerline = null;
            Dictionary <string, string> headers = new Dictionary <string, string>();

            while ((headerline = readLine(instream)).Trim().Length != 0)
            {
                if (headerline.StartsWith("POST"))
                {
                    int firstSpace  = headerline.IndexOf(' ');
                    int secondSpace = headerline.IndexOf(' ', firstSpace + 1);
                    if ((firstSpace == -1) || (secondSpace == -1))
                    {
                        throw new Exception("Malformed HTTP request line, can't parse POST context path");
                    }
                    receivedContextPath = headerline.Substring(firstSpace, secondSpace - firstSpace);
                }
                else
                {
                    int colon = headerline.IndexOf(":");
                    if (colon == -1)
                    {
                        throw new Exception("Malformed HTTP header - no field/data delimiter colon");
                    }
                    headers.Add(headerline.Substring(0, colon).ToUpper(), headerline.Substring(colon + 1).Trim());
                }
            }
            string ctype = headers["CONTENT-TYPE"];

            if (ctype == null)
            {
                throw new Exception("Malformed HTTP headers - no Content-Type found");
            }
            if (ctype.Contains("multipart/related"))
            {
                mimeboundary = setMimeBoundary(ctype);
            }
            receivedHost = headers["HOST"];
            string clen = headers["CONTENT-LENGTH"];

            if (clen == null)
            {
                throw new Exception("Malformed HTTP headers - no Content-Length found");
            }
            int contentlength = Int32.Parse(clen);

            soapAction = headers["SOAPACTION"];
            soapAction = soapAction.Replace('"', ' ').Trim();

            // There is a bug in Spine-hosted services that turns a SOAPaction starting with
            // "urn:" into "urn:urn:" - fix this if we find it.
            //
            if (soapAction.StartsWith("urn:urn:"))
            {
                soapAction = soapAction.Substring(4);
            }

            // Read content-length bytes and parse out the various parts of the
            // received message.
            // TODO: Put in proper handling.
            //
            Byte[] wire      = new Byte[contentlength];
            int    bytesRead = 0;

            while (bytesRead < contentlength)
            {
                bytesRead += instream.Read(wire, bytesRead, contentlength - bytesRead);
            }
            string msg = Encoding.UTF8.GetString(wire);

            // Split on the mimeboundary. "msg" doesn't contain the HTTP headers so we should
            // just be able to walk through the attachments. If we can't, report an exception
            //
            int startPosition = msg.IndexOf(mimeboundary, 0);

            if (startPosition == -1)
            {
                // Need to handle the case where the content is
                // actually an asynchronous ebXML ack.
                //
                // If content-type is text/xml and soapaction contains Acknowledgment or MessageError,
                // it is an ack/nack. If we get one of these we need to log it and tell the connection
                // manager about it. But we don't need to do any further processing.
                //
                if (ctype.ToLower().StartsWith("text/xml"))
                {
                    if (soapAction.Contains("Acknowledgment"))
                    {
                        // Remove from requests, and exit
                        string a = EbXmlAcknowledgment.getAckedMessageId(msg);
                        if (a == null)
                        {
                            EventLog logger = new EventLog("Application");
                            logger.Source = ConnectionManager.LOGSOURCE;
                            StringBuilder sb = new StringBuilder("Failed to extract message id reference from Acknowledgment: ");
                            sb.Append(msg);
                            logger.WriteEntry(sb.ToString(), EventLogEntryType.Error);
                            return;
                        }
                        ConnectionManager cm = ConnectionManager.getInstance();
                        cm.registerAck(a);
                        return;
                    }
                    if (soapAction.Contains("MessageError"))
                    {
                        // Remove from requests, and exit
                        string a = EbXmlAcknowledgment.getAckedMessageId(msg);
                        if (a == null)
                        {
                            EventLog logger = new EventLog("Application");
                            logger.Source = ConnectionManager.LOGSOURCE;
                            StringBuilder sb = new StringBuilder("Failed to extract message id reference from MessageError: ");
                            sb.Append(msg);
                            logger.WriteEntry(sb.ToString(), EventLogEntryType.Error);
                            return;
                        }
                        EventLog l = new EventLog("Application");
                        l.Source = ConnectionManager.LOGSOURCE;
                        StringBuilder sbe = new StringBuilder("EbXML MessageError received: ");
                        sbe.Append(msg);
                        l.WriteEntry(sbe.ToString(), EventLogEntryType.Error);

                        ConnectionManager cm = ConnectionManager.getInstance();
                        cm.registerAck(a);
                        return;
                    }
                }
                throw new Exception("Malformed message");
            }
            int  endPosition    = 0;
            int  partCount      = 0;
            bool gotEndBoundary = false;

            do
            {
                startPosition += mimeboundary.Length;
                endPosition    = msg.IndexOf(mimeboundary, startPosition);
                if (endPosition == -1)
                {
                    gotEndBoundary = true;
                }
                else
                {
                    switch (partCount)
                    {
                    case 0:
                        header = new EbXmlHeader(msg.Substring(startPosition, endPosition - startPosition));
                        if (header.Timestamp != null)
                        {
                            started = DateTime.Parse(header.Timestamp);
                            // We don't know how many attempts were actually made, so assume
                            // only one try at the start time.
                            //
                            lastTry = DateTime.Parse(header.Timestamp);
                            tries   = 1;
                        }
                        break;

                    case 1:
                        hl7message = new SpineHL7Message(msg.Substring(startPosition, endPosition - startPosition));
                        break;

                    default:
                        if (attachments == null)
                        {
                            attachments = new List <Attachment>();
                        }
                        // IMPROVEMENT: Make this more flexible to be able to support multiple types of
                        // ITK trunk message, just in case
                        //
                        if (soapAction.Contains("COPC_IN000001GB01"))
                        {
                            attachments.Add(new ITKDistributionEnvelopeAttachment(msg.Substring(startPosition, endPosition - startPosition)));
                        }
                        else
                        {
                            attachments.Add(new GeneralAttachment(msg.Substring(startPosition, endPosition - startPosition)));
                        }
                        break;
                    }
                    partCount++;
                    startPosition = endPosition;
                }
            }while (!gotEndBoundary);
//            persistDuration = (int)(ConnectionManager.getInstance().getPersistDuration(header.SvcIA).TotalSeconds);
        }
        /**
         * Used to assemble an EbXmlMessage from the given Stream, which has been accepted from the network.
         * This expects to get the inbound HTTP stream (or at least an SslStream) from the start, because it
         * begins processing with the HTTP POST.
         */
        public EbXmlMessage(Stream instream)
        {
            // Assemble from network - note that Spine messages are NOT chunked
            //
            string headerline = null;
            Dictionary<string, string> headers = new Dictionary<string, string>();
            while ((headerline = readLine(instream)).Trim().Length != 0)
            {
                if (headerline.StartsWith("POST"))
                {
                    int firstSpace = headerline.IndexOf(' ');
                    int secondSpace = headerline.IndexOf(' ', firstSpace + 1);
                    if ((firstSpace == -1) || (secondSpace == -1))
                        throw new Exception("Malformed HTTP request line, can't parse POST context path");
                    receivedContextPath = headerline.Substring(firstSpace, secondSpace - firstSpace);
                }
                else
                {
                    int colon = headerline.IndexOf(":");
                    if (colon == -1)
                    {
                        throw new Exception("Malformed HTTP header - no field/data delimiter colon");
                    }
                    headers.Add(headerline.Substring(0, colon).ToUpper(), headerline.Substring(colon + 1).Trim());
                }
            }
            string ctype = headers["CONTENT-TYPE"];
            if (ctype == null) {
                throw new Exception("Malformed HTTP headers - no Content-Type found");
            }
            if (ctype.Contains("multipart/related")) {
                mimeboundary = setMimeBoundary(ctype);
            }
            receivedHost = headers["HOST"];
            string clen = headers["CONTENT-LENGTH"];
            if (clen == null)
            {
                throw new Exception("Malformed HTTP headers - no Content-Length found");
            }
            int contentlength = Int32.Parse(clen);
            soapAction = headers["SOAPACTION"];
            soapAction = soapAction.Replace('"', ' ').Trim();

            // There is a bug in Spine-hosted services that turns a SOAPaction starting with
            // "urn:" into "urn:urn:" - fix this if we find it.
            //
            if (soapAction.StartsWith("urn:urn:"))
                soapAction = soapAction.Substring(4);

            // Read content-length bytes and parse out the various parts of the
            // received message.
            // TODO: Put in proper handling.
            //
            Byte[] wire = new Byte[contentlength];
            int bytesRead = 0;
            while (bytesRead < contentlength)
            {
                bytesRead += instream.Read(wire, bytesRead, contentlength - bytesRead);
            }
            string msg = Encoding.UTF8.GetString(wire);

            // Split on the mimeboundary. "msg" doesn't contain the HTTP headers so we should
            // just be able to walk through the attachments. If we can't, report an exception
            //
            int startPosition = msg.IndexOf(mimeboundary, 0);
            if (startPosition == -1)
            {
                // Need to handle the case where the content is
                // actually an asynchronous ebXML ack.
                //
                // If content-type is text/xml and soapaction contains Acknowledgment or MessageError,
                // it is an ack/nack. If we get one of these we need to log it and tell the connection
                // manager about it. But we don't need to do any further processing.
                //
                if (ctype.ToLower().StartsWith("text/xml"))
                {
                    if (soapAction.Contains("Acknowledgment"))
                    {
                        // Remove from requests, and exit
                        string a = EbXmlAcknowledgment.getAckedMessageId(msg);
                        if (a == null)
                        {
                            EventLog logger = new EventLog("Application");
                            logger.Source = ConnectionManager.LOGSOURCE;
                            StringBuilder sb = new StringBuilder("Failed to extract message id reference from Acknowledgment: ");
                            sb.Append(msg);
                            logger.WriteEntry(sb.ToString(), EventLogEntryType.Error);
                            return;
                        }
                        ConnectionManager cm = ConnectionManager.getInstance();
                        cm.registerAck(a);
                        return;
                    }
                    if (soapAction.Contains("MessageError"))
                    {
                        // Remove from requests, and exit
                        string a = EbXmlAcknowledgment.getAckedMessageId(msg);
                        if (a == null)
                        {
                            EventLog logger = new EventLog("Application");
                            logger.Source = ConnectionManager.LOGSOURCE;
                            StringBuilder sb = new StringBuilder("Failed to extract message id reference from MessageError: ");
                            sb.Append(msg);
                            logger.WriteEntry(sb.ToString(), EventLogEntryType.Error);
                            return;
                        }
                        EventLog l = new EventLog("Application");
                        l.Source = ConnectionManager.LOGSOURCE;
                        StringBuilder sbe = new StringBuilder("EbXML MessageError received: ");
                        sbe.Append(msg);
                        l.WriteEntry(sbe.ToString(), EventLogEntryType.Error);

                        ConnectionManager cm = ConnectionManager.getInstance();
                        cm.registerAck(a);
                        return;
                    }
                }
                throw new Exception("Malformed message");
            }
            int endPosition = 0;
            int partCount = 0;
            bool gotEndBoundary = false;
            do
            {
                startPosition += mimeboundary.Length;
                endPosition = msg.IndexOf(mimeboundary, startPosition);
                if (endPosition == -1)
                {
                    gotEndBoundary = true;
                }
                else
                {
                    switch (partCount)
                    {
                        case 0:
                            header = new EbXmlHeader(msg.Substring(startPosition, endPosition - startPosition));
                            if (header.Timestamp != null)
                            {
                                started = DateTime.Parse(header.Timestamp);
                                // We don't know how many attempts were actually made, so assume
                                // only one try at the start time.
                                //
                                lastTry = DateTime.Parse(header.Timestamp);
                                tries = 1;
                            }
                            break;
                        case 1:
                            hl7message = new SpineHL7Message(msg.Substring(startPosition, endPosition - startPosition));
                            break;
                        default:
                            if (attachments == null)
                                attachments = new List<Attachment>();
                            // IMPROVEMENT: Make this more flexible to be able to support multiple types of
                            // ITK trunk message, just in case
                            //
                            if (soapAction.Contains("COPC_IN000001GB01"))
                            {
                                attachments.Add(new ITKDistributionEnvelopeAttachment(msg.Substring(startPosition, endPosition - startPosition)));
                            }
                            else
                            {
                                attachments.Add(new GeneralAttachment(msg.Substring(startPosition, endPosition - startPosition)));
                            }
                            break;
                    }
                    partCount++;
                    startPosition = endPosition;
                }
            }
            while (!gotEndBoundary);
            //            persistDuration = (int)(ConnectionManager.getInstance().getPersistDuration(header.SvcIA).TotalSeconds);
        }
 /**
  * Construct an EbXmlMessage for sending.
  *
  * @param s An SdSTransmissionDetails instance for recipient information
  * @param m SpineHL7Message instance to be sent
  * @param c Reference to an SDSconnection for resolving URLs
  */
 public EbXmlMessage(SdsTransmissionDetails s, SpineHL7Message m)
 {
     SDSconnection c = ConnectionManager.getInstance().SdsConnection;
     odsCode = s.Org;
     header = new EbXmlHeader(this, s);
     type = EBXML;
     hl7message = m;
     string svcurl = c.resolveUrl(s.SvcIA);
     if (svcurl == null)
         resolvedUrl = s.Url;
     else
         resolvedUrl = svcurl;
     if (s.Retries != SdsTransmissionDetails.NOT_SET)
     {
         retryCount = s.Retries;
         minRetryInterval = s.RetryInterval;
         persistDuration = s.PersistDuration;
     }
     attachments = new List<Attachment>();
     persistable = (s.Retries > 0);
 }