/** * Construct an EbXmlHeader for the given EbXmlMessage, using the transmission details. * * @param msg The EbXmlMessage for which this will be the header * @param s An SdsTransmissionDetails instance containing information on sending this message type to the recipient */ public EbXmlHeader(EbXmlMessage msg, SdsTransmissionDetails s) { if (bootException != null) { throw bootException; } ebxml = msg; messageId = Guid.NewGuid().ToString().ToUpper(); setMimeType(EBXMLHEADERMIMETYPE); lock (messageId) { if (ebxmlheadertemplate == null) { Assembly assembly = Assembly.GetExecutingAssembly(); StreamReader sr = new StreamReader(assembly.GetManifestResourceStream(EBXMLHEADERTEMPLATE)); StringBuilder sb = new StringBuilder(); try { String line = null; while ((line = sr.ReadLine()) != null) { sb.Append(line); sb.Append("\r\n"); } ebxmlheadertemplate = sb.ToString(); } catch (Exception e) { bootException = e; throw e; } } } service = s.Service; interactionid = s.InteractionId; cpaid = s.CPAid; soapActor = s.SoapActor; toPartyKey = s.PartyKey; duplicateElimination = s.DuplicateElimination.Equals("always"); ackrequested = s.AckRequested.Equals("always"); syncreply = s.SyncReply.Equals("MSHSignalsOnly"); }
public void handle(Sendable s) { EbXmlMessage ebxml = (EbXmlMessage)s; ITKDistributionEnvelopeAttachment a = (ITKDistributionEnvelopeAttachment)ebxml.Attachments[ITKATTACHMENT]; DistributionEnvelope d = a.DistributionEnvelope; IDistributionEnvelopeHandler h = null; try { h = handlers[d.getService()]; } catch (KeyNotFoundException) { EventLog logger = new EventLog("Application"); logger.Source = LOGSOURCE; StringBuilder sb = new StringBuilder("No explicit handler found for "); sb.Append(d.getService()); sb.Append(" using default DefaultFileSaveDistributionEnvelopeHandler instead"); logger.WriteEntry(sb.ToString(), EventLogEntryType.Warning); h = new DefaultFileSaveDistributionEnvelopeHandler(); } h.handle(d); }
/** * Construct an EbXmlHeader for the given EbXmlMessage, using the transmission details. * * @param msg The EbXmlMessage for which this will be the header * @param s An SdsTransmissionDetails instance containing information on sending this message type to the recipient */ public EbXmlHeader(EbXmlMessage msg, SdsTransmissionDetails s) { if (bootException != null) throw bootException; ebxml = msg; messageId = Guid.NewGuid().ToString().ToUpper(); setMimeType(EBXMLHEADERMIMETYPE); lock (messageId) { if (ebxmlheadertemplate == null) { Assembly assembly = Assembly.GetExecutingAssembly(); StreamReader sr = new StreamReader(assembly.GetManifestResourceStream(EBXMLHEADERTEMPLATE)); StringBuilder sb = new StringBuilder(); try { String line = null; while ((line = sr.ReadLine()) != null) { sb.Append(line); sb.Append("\r\n"); } ebxmlheadertemplate = sb.ToString(); } catch (Exception e) { bootException = e; throw e; } } } service = s.Service; interactionid = s.InteractionId; cpaid = s.CPAid; soapActor = s.SoapActor; toPartyKey = s.PartyKey; duplicateElimination = s.DuplicateElimination.Equals("always"); ackrequested = s.AckRequested.Equals("always"); syncreply = s.SyncReply.Equals("MSHSignalsOnly"); }
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]); }
public override void setResponse(Sendable r) { response = (EbXmlMessage)r; }
/** * Called in its own thread to process the inbound message on the given socket. Reads the * message, returns any synchronous or asynchronous acknowledgment, and logs the message id in the de-duplication list. * If the id has not been seen before (according to the list), calls ConnectionManager.receive(). * * @param Clear-text accepted socket */ private void processMessage(Socket s) { // Log received ebXML message ids and add to it where "duplicate // elimination" is set. Do this in memory - if we go down between retries on long- // duration interactions we'll incorrectly not detect the duplicate, but that will // be a recognised limitation for now, and is supposed to be caught by HL7 de- // duplication anyway. // EbXmlMessage msg = null; try { ConnectionManager cm = ConnectionManager.getInstance(); NetworkStream n = new NetworkStream(s); SslStream ssl = new SslStream(n, false, validateRemoteCertificate, getLocalCertificate); // FIXME: Require client certificate - but leave it for now // ssl.AuthenticateAsServer(cm.getCertificate()); msg = new EbXmlMessage(ssl); string ack = makeSynchronousAck(msg); if (ack != null) { ssl.Write(Encoding.UTF8.GetBytes(ack)); ssl.Flush(); } ssl.Close(); // If we have data for it, DateTime.Now + persistDuration. The trouble is that // the persistDuration isn't actually carried in the message. Easiest is *probably* // to cache SDS details for "my party key" for all received messages, which will // require a "tool" to do the calls. // Dictionary<string, TimeSpan> pd = cm.ReceivedPersistDurations; if (pd != null) { bool notSeenBefore = true; lock (requestLock) { notSeenBefore = (!receivedIds.ContainsKey(msg.Header.MessageId)); } if (notSeenBefore) { try { // TimeSpan ts = pd[msg.SoapAction]; TimeSpan ts = pd[msg.Header.SvcIA]; DateTime expireTime = DateTime.Now; expireTime = expireTime.Add(ts); lock (requestLock) { receivedIds.Add(msg.Header.MessageId, expireTime) ; } } catch (KeyNotFoundException) { } cm.receive(msg); } // No "else" - if the message id is in the "receivedIds" set then we want // to do the ack but nothing else. } else { cm.receive(msg); } } catch (Exception e) { EventLog logger = new EventLog("Application"); logger.Source = LOGSOURCE; StringBuilder sb = new StringBuilder("Error receiving message from"); sb.Append(s.RemoteEndPoint.ToString()); sb.Append(" : "); sb.Append(e.ToString()); logger.WriteEntry(sb.ToString(), EventLogEntryType.Error); if (msg != null) doAsynchronousNack(msg); return; } doAsynchronousAck(msg); }
/** * Checks to see if the EbXmlMessage should be acknowledged synchronously, and just returns * a zero-length string if not. Otherwise, makes an ebXML acknowledgment and returns it as * a string. * * @param EbXmlMessage to acknowledge */ private string makeSynchronousAck(EbXmlMessage msg) { if (!msg.Header.DuplicateElimination) return EMPTY_RESPONSE; if (!msg.Header.SyncReply) return EMPTY_RESPONSE; StringBuilder hdr = new StringBuilder(ACK_HTTP_HEADER); string ack = makeEbXmlAck(msg, true); hdr.Replace("__CONTENT_LENGTH__", ack.Length.ToString()); hdr.Append(ack); return hdr.ToString(); }
/** * Assembles an ebXML acknowledgment. */ private string makeEbXmlAck(EbXmlMessage msg, bool replaceCpaId) { StringBuilder sb = new StringBuilder(ebxmlacktemplate); sb.Replace("__FROM_PARTY_ID__", msg.Header.FromPartyKey); //sb.Replace("__FROM_PARTY_ID__", msg.Header.ToPartyKey); string mp = ConnectionManager.getInstance().SdsConnection.MyPartyKey; sb.Replace("__TO_PARTY_ID__", mp); sb.Replace("__ORIGINAL_MESSAGE_ID__", msg.getMessageId()); sb.Replace("__CONVERSATION_ID__", msg.Header.ConversationId); if (replaceCpaId) sb.Replace("__CPA_ID__", msg.Header.CpaId); sb.Replace("__ACK_MESSAGE_ID__", System.Guid.NewGuid().ToString().ToUpper()); sb.Replace("__ACK_TIMESTAMP__", DateTime.Now.ToString(EbXmlHeader.ISO8601DATEFORMAT)); return sb.ToString(); }
/** * TODO: Constructs an asynchronous ebXML error message. Where do we get error information from ? * * @param EbXml message to NACK */ private void doAsynchronousNack(EbXmlMessage msg) { // If "msg" is an ack or message error if (msg.Header == null) return; // If "msg" is "unreliable" if (!msg.Header.DuplicateElimination) return; // If we've already returned the ack synchronously if (msg.Header.SyncReply) return; }
/** * Checks to see if the given EbXmlMessage is acknowledged asynchronously, and just returns * if not. Otherwise, constructs an EbXMLAcknowledgment addressed to the sender of "msg", * and calls the ConnectionManager to send it. * * @param EbXmlMessage to acknowledge */ private void doAsynchronousAck(EbXmlMessage msg) { if (msg == null) return; if (!msg.Header.DuplicateElimination) return; if (msg.Header.SyncReply) return; StringBuilder a = new StringBuilder(makeEbXmlAck(msg, false)); ConnectionManager cm = ConnectionManager.getInstance(); SDSconnection sds = cm.SdsConnection; string ods = msg.Header.FromPartyKey.Substring(0, msg.Header.FromPartyKey.IndexOf("-")); List<SdsTransmissionDetails> sdsdetails = sds.getTransmissionDetails(ACKSERVICE, ods, null, msg.Header.FromPartyKey); a.Replace("__CPA_ID__", sdsdetails[0].CPAid); EbXmlAcknowledgment ack = new EbXmlAcknowledgment(a.ToString()); ack.setHost(sdsdetails[0].Url); cm.send(ack, sdsdetails[0]); }