/** * 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 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"); }
/** * Called by load() */ private void loadInteraction(string d) { string svcinteraction = d.Substring(d.LastIndexOf("\\") + 1); StringBuilder sbi = new StringBuilder(svcinteraction); sbi.Replace("=", ":"); svcinteraction = sbi.ToString(); IEnumerable <string> files = Directory.EnumerateFiles(d); List <SdsTransmissionDetails> tx = new List <SdsTransmissionDetails>(); transmission.Add(svcinteraction, tx); foreach (string f in files) { string sdstransmission = null; using (StreamReader tr = new StreamReader(f)) { sdstransmission = tr.ReadToEnd(); } SdsTransmissionDetails td = JsonConvert.DeserializeObject <SdsTransmissionDetails>(sdstransmission); tx.Add(td); } }
/** * 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"); }
internal void cacheTransmissionDetail(SdsTransmissionDetails sds) { if (transmission.ContainsKey(sds.SvcIA)) { List <SdsTransmissionDetails> l = transmission[sds.SvcIA]; bool replaced = false; // FIXME: This is *probably* broken, but silently because the s.Asid.Equals will always fail // as the ASID list in "s" is never the same physical thing as the one in "sds". If it ever // did match we'd get some sort of concurrency fail updating "l" when we're still reading it // in the foreach loop. Look at the Java code instead. foreach (SdsTransmissionDetails s in l) { if (s.Asid.Equals(sds.Asid)) { l.Remove(s); l.Add(sds); replaced = true; break; } } if (!replaced) { l.Add(sds); } } else { List <SdsTransmissionDetails> l = new List <SdsTransmissionDetails>(); l.Add(sds); transmission.Add(sds.SvcIA, l); } // Write to cache // 1. See if we have a directory entry for the SvcIA // 2. Create one if necessary // 3. Make a file (StreamWriter) for the asid // 4. Serialise "sds" to JSON IEnumerable <string> svcs = Directory.EnumerateDirectories(cacheDir); bool exists = false; // FIXME: BUG: This will always fail, since the SvcIA has colons and the file names have equals // signs (noticed during porting) foreach (string s in svcs) { if (s.Contains(sds.SvcIA)) { exists = true; break; } } StringBuilder svciadir = new StringBuilder(cacheDir); svciadir.Append("\\"); svciadir.Append(sds.SvcIA); svciadir.Replace(":", "="); // Put the colon back after the drive letter, duh! svciadir.Replace('=', ':', 0, 2); if (!exists) { Directory.CreateDirectory(svciadir.ToString()); } svciadir.Append("\\"); svciadir.Append(sds.PartyKey); string json = JsonConvert.SerializeObject(sds); using (StreamWriter sw = new StreamWriter(svciadir.ToString())) { sw.Write(json); } }
/** * Called from the public getTransmissionDetails() to search SDS when there are no * matching records in the local cache. Anything that is read is cached locally. */ private List<SdsTransmissionDetails> ldapGetTransmissionDetails(string s, string o, string a, string p) { if (certificate == null) return null; // Two searches: one on nhsMHS to get all the entries for the service for the given organisation, // and then another on nhsAS to get all the AS entries (optionally filtering on ASID). Then build the // list of SdsTransmissionDetails, and add them to the cache. StringBuilder sbMhs = new StringBuilder(MHSQUERY); // replace the tags in MHSQUERY __SERVICE__ and __ORG__ sbMhs.Replace("__SERVICE__", s); sbMhs.Replace("__ORG__", o); if (p != null) { StringBuilder pkf = new StringBuilder(PKFILTER); pkf.Replace("__PK__", p); sbMhs.Replace("__PARTYKEYFILTER__", pkf.ToString()); } else { sbMhs.Replace("__PARTYKEYFILTER__", ""); } List<SdsTransmissionDetails> results = null; SearchRequest srMhs = new SearchRequest(serviceRoot, sbMhs.ToString(), SearchScope.Subtree, ALL_ATTRIBUTES); int ldapPort = (opentest) ? LDAP_PORT : LDAPS_PORT; using (LdapConnection connection = new LdapConnection(new LdapDirectoryIdentifier(server, Convert.ToInt32(ldapPort), true, false))) { connection.AuthType = AuthType.Anonymous; if (opentest) { connection.SessionOptions.SecureSocketLayer = false; } else { connection.SessionOptions.QueryClientCertificate = getCertificate; connection.SessionOptions.VerifyServerCertificate = verifyCertificate; connection.SessionOptions.SecureSocketLayer = true; } connection.SessionOptions.ProtocolVersion = 3; List<Dictionary<string,List<string>>> dr = doSearch(connection, srMhs); if (dr == null) return null; results = new List<SdsTransmissionDetails>(); // "dr" at this point contains a list of nhsMHS objects for the requested interaction, ODS code // and party key if it was specified. Need to build the transmission details from those, and // get the ASIDs. // foreach (Dictionary<string,List<string>> mhs in dr) { SdsTransmissionDetails sds = new SdsTransmissionDetails(mhs); results.Add(sds); if (a == null) { // ASID filtering... need to retrieve the ASID, note that there is only one partykey attribute // StringBuilder sbAs = new StringBuilder(ASQUERY); sbAs.Replace("__SERVICE__", s); sbAs.Replace("__ORG__", o); sbAs.Replace("__PK__", mhs[PARTYKEY][SINGLEVALUE]); SearchRequest srAs = new SearchRequest(serviceRoot, sbAs.ToString(), SearchScope.Subtree, UNIQUE_IDENTIFIER); List<Dictionary<string,List<string>>> asResponse = doSearch(connection, srAs); // Error, but it is already reported, just don't try to populate if (asResponse != null) { List<string> asids = new List<string>(); foreach (Dictionary<string, List<string>> nhsas in asResponse) { // Get the "uniqueIdentifier" from each nhsAS object (i.e. the ASID) string asid = nhsas[UNIQUEIDENTIFIER][SINGLEVALUE]; asids.Add(asid); } sds.Asid = asids; } } else { // FIXME: This assumes that the ASID is valid and correct. If it isn't any Spine request // based on it will fail. Assume for now, and look at how to make better later. if (sds.Asid == null) sds.Asid = new List<string>(); sds.Asid.Add(a); } } } // Consider putting this in a thread if (cache != null) { foreach (SdsTransmissionDetails sdstd in results) { cache.cacheTransmissionDetail(sdstd); } } return results; }
internal void cacheTransmissionDetail(SdsTransmissionDetails sds) { if (transmission.ContainsKey(sds.SvcIA)) { List<SdsTransmissionDetails> l = transmission[sds.SvcIA]; bool replaced = false; // FIXME: This is *probably* broken, but silently because the s.Asid.Equals will always fail // as the ASID list in "s" is never the same physical thing as the one in "sds". If it ever // did match we'd get some sort of concurrency fail updating "l" when we're still reading it // in the foreach loop. Look at the Java code instead. foreach (SdsTransmissionDetails s in l) { if (s.Asid.Equals(sds.Asid)) { l.Remove(s); l.Add(sds); replaced = true; break; } } if (!replaced) l.Add(sds); } else { List<SdsTransmissionDetails> l = new List<SdsTransmissionDetails>(); l.Add(sds); transmission.Add(sds.SvcIA, l); } // Write to cache // 1. See if we have a directory entry for the SvcIA // 2. Create one if necessary // 3. Make a file (StreamWriter) for the asid // 4. Serialise "sds" to JSON IEnumerable<string> svcs = Directory.EnumerateDirectories(cacheDir); bool exists = false; // FIXME: BUG: This will always fail, since the SvcIA has colons and the file names have equals // signs (noticed during porting) foreach (string s in svcs) { if (s.Contains(sds.SvcIA)) { exists = true; break; } } StringBuilder svciadir = new StringBuilder(cacheDir); svciadir.Append("\\"); svciadir.Append(sds.SvcIA); svciadir.Replace(":", "="); // Put the colon back after the drive letter, duh! svciadir.Replace('=', ':', 0, 2); if (!exists) Directory.CreateDirectory(svciadir.ToString()); svciadir.Append("\\"); svciadir.Append(sds.PartyKey); string json = JsonConvert.SerializeObject(sds); using (StreamWriter sw = new StreamWriter(svciadir.ToString())) { sw.Write(json); } }
/** * 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; }
/** * Called from the public getTransmissionDetails() to search SDS when there are no * matching records in the local cache. Anything that is read is cached locally. */ private List <SdsTransmissionDetails> ldapGetTransmissionDetails(string s, string o, string a, string p) { if (certificate == null) { return(null); } // Two searches: one on nhsMHS to get all the entries for the service for the given organisation, // and then another on nhsAS to get all the AS entries (optionally filtering on ASID). Then build the // list of SdsTransmissionDetails, and add them to the cache. StringBuilder sbMhs = new StringBuilder(MHSQUERY); // replace the tags in MHSQUERY __SERVICE__ and __ORG__ sbMhs.Replace("__SERVICE__", s); sbMhs.Replace("__ORG__", o); if (p != null) { StringBuilder pkf = new StringBuilder(PKFILTER); pkf.Replace("__PK__", p); sbMhs.Replace("__PARTYKEYFILTER__", pkf.ToString()); } else { sbMhs.Replace("__PARTYKEYFILTER__", ""); } List <SdsTransmissionDetails> results = null; SearchRequest srMhs = new SearchRequest(serviceRoot, sbMhs.ToString(), SearchScope.Subtree, ALL_ATTRIBUTES); int ldapPort = (opentest) ? LDAP_PORT : LDAPS_PORT; using (LdapConnection connection = new LdapConnection(new LdapDirectoryIdentifier(server, Convert.ToInt32(ldapPort), true, false))) { connection.AuthType = AuthType.Anonymous; if (opentest) { connection.SessionOptions.SecureSocketLayer = false; } else { connection.SessionOptions.QueryClientCertificate = getCertificate; connection.SessionOptions.VerifyServerCertificate = verifyCertificate; connection.SessionOptions.SecureSocketLayer = true; } connection.SessionOptions.ProtocolVersion = 3; List <Dictionary <string, List <string> > > dr = doSearch(connection, srMhs); if (dr == null) { return(null); } results = new List <SdsTransmissionDetails>(); // "dr" at this point contains a list of nhsMHS objects for the requested interaction, ODS code // and party key if it was specified. Need to build the transmission details from those, and // get the ASIDs. // foreach (Dictionary <string, List <string> > mhs in dr) { SdsTransmissionDetails sds = new SdsTransmissionDetails(mhs); results.Add(sds); if (a == null) { // ASID filtering... need to retrieve the ASID, note that there is only one partykey attribute // StringBuilder sbAs = new StringBuilder(ASQUERY); sbAs.Replace("__SERVICE__", s); sbAs.Replace("__ORG__", o); sbAs.Replace("__PK__", mhs[PARTYKEY][SINGLEVALUE]); SearchRequest srAs = new SearchRequest(serviceRoot, sbAs.ToString(), SearchScope.Subtree, UNIQUE_IDENTIFIER); List <Dictionary <string, List <string> > > asResponse = doSearch(connection, srAs); // Error, but it is already reported, just don't try to populate if (asResponse != null) { List <string> asids = new List <string>(); foreach (Dictionary <string, List <string> > nhsas in asResponse) { // Get the "uniqueIdentifier" from each nhsAS object (i.e. the ASID) string asid = nhsas[UNIQUEIDENTIFIER][SINGLEVALUE]; asids.Add(asid); } sds.Asid = asids; } } else { // FIXME: This assumes that the ASID is valid and correct. If it isn't any Spine request // based on it will fail. Assume for now, and look at how to make better later. if (sds.Asid == null) { sds.Asid = new List <string>(); } sds.Asid.Add(a); } } } // Consider putting this in a thread if (cache != null) { foreach (SdsTransmissionDetails sdstd in results) { cache.cacheTransmissionDetail(sdstd); } } return(results); }
/** * 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; } }
/** * 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); }