private Dictionary <string, TimeSpan> loadReceivedPersistDurations() { string pdFile = (string)Registry.GetValue(CONNECTION_MANAGER_REGSITRY_KEY, PERSIST_DIRATION_FILE_REGVAL, ""); StreamReader sr = null; if (pdFile.Length == 0) { Assembly assembly = Assembly.GetExecutingAssembly(); sr = new StreamReader(assembly.GetManifestResourceStream(INTERNAL_PERSIST_DURATIONS)); } else { try { sr = new StreamReader(new FileStream(pdFile, FileMode.Open)); } catch (Exception e) { EventLog logger = new EventLog("Application"); logger.Source = LOGSOURCE; StringBuilder sbe = new StringBuilder("Cannot read inbound persistDuration data: "); sbe.Append(e.ToString()); sbe.Append("ebXml duplicate elimination NOT available"); logger.WriteEntry(sbe.ToString(), EventLogEntryType.Warning); return(null); } } Dictionary <string, TimeSpan> pd = new Dictionary <string, TimeSpan>(); string line = null; while ((line = sr.ReadLine()) != null) { try { string[] fields = line.Split(TABSEPARATOR); // char[] f = fields[0].ToCharArray(); // f[fields[0].LastIndexOf(':')] = '/'; // fields[0] = new string(f); int s = SdsTransmissionDetails.iso8601DurationToSeconds(fields[1]); TimeSpan t = new TimeSpan(0, 0, s); pd.Add(fields[0], t); } catch (Exception e) { EventLog logger = new EventLog("Application"); logger.Source = LOGSOURCE; StringBuilder sbe = new StringBuilder("Cannot read inbound persistDuration data: "); sbe.Append(e.ToString()); sbe.Append("ebXml duplicate elimination NOT available"); logger.WriteEntry(sbe.ToString(), EventLogEntryType.Warning); return(null); } } sr.Close(); return(pd); }
/** * Wrapper round the transmission and, where relevant retry and receipt of an asynchronous * response, for a "Sendable" message using the given transmission details resolved either * from SDS or the local SDS cache. This does the actual transmission in a separate thread * so will return immediately. * * @param Sendable s Message to send * @param SdsTransmissionDetails c retrieved transmission details for the message type/recipient pair */ public void send(Sendable s, SdsTransmissionDetails c) { if (!c.IsSynchronous) { listen(); // Don't expect an ack if we're sending an asynchronous ack, but otherwise do // do that we have something to attach a response to, if we're going to get one. // if (!(s.Type == Sendable.ACK) && (c.DuplicateElimination.Equals("always"))) { if (!requests.ContainsKey(s.getMessageId())) { requests.Add(s.getMessageId(), s); } } } (new Thread(() => this.doTransmission(s))).Start(); }
/** Called at start-up if the system needs to load any persisted, reliable messages * for sending. This applies the persist duration for the message type to the declared * timestamp, and will run the expire() method on anything that has expired whilst * the MHS was down. */ public void loadPersistedMessages() { string[] files = Directory.GetFiles(messageDirectory); EbXmlMessage ebxml = null; foreach (String f in files) { using (FileStream fs = new FileStream(f, FileMode.Open)) { try { ebxml = new EbXmlMessage(fs); // "f" is now of the form "odscode_messageid" so get the ods code and set it here. string ods = f.Substring(0, f.IndexOf("_")).Substring(f.LastIndexOf("\\") + 1); ebxml.setOdsCode(ods); // Do an SDS lookup and populate retry interval, persist duration // and retry cound in ebxml. List <SdsTransmissionDetails> sdsdetails = sdsConnection.getTransmissionDetails(ebxml.Header.SvcIA, ods, ebxml.HL7Message.ToAsid, ebxml.Header.ToPartyKey); if (sdsdetails.Count == 0) { throw new Exception("Cannot resolve SDS details for persisted message: " + f); } if (sdsdetails.Count > 1) { throw new Exception("Ambiguous SDS details for persisted message: " + f); } SdsTransmissionDetails sds = sdsdetails[0]; ebxml.PersistDuration = sds.PersistDuration; ebxml.RetryCount = sds.Retries; ebxml.RetryInterval = sds.RetryInterval; } catch (Exception e) { EventLog logger = new EventLog("Application"); logger.Source = LOGSOURCE; StringBuilder sbe = new StringBuilder("Failed to load persisted ebXml message "); sbe.Append(f); sbe.Append(" due to exception "); sbe.Append(e.Message); sbe.Append(" at "); sbe.Append(e.StackTrace); logger.WriteEntry(sbe.ToString(), EventLogEntryType.FailureAudit); continue; } } DateTime check = DateTime.Now; TimeSpan pd = getPersistDuration(ebxml.Header.SvcIA); DateTime expiryTime = ebxml.Started.Add(pd); if (expiryTime.CompareTo(check) < 0) { depersist(ebxml); ebxml.Expire(); } else { requests.Add(ebxml.getMessageId(), ebxml); } } }
/** * Wrapper round the transmission and, where relevant retry and receipt of an asynchronous * response, for a "Sendable" message using the given transmission details resolved either * from SDS or the local SDS cache. This does the actual transmission in a separate thread * so will return immediately. * * @param Sendable s Message to send * @param SdsTransmissionDetails c retrieved transmission details for the message type/recipient pair */ public void send(Sendable s, SdsTransmissionDetails c) { if (!c.IsSynchronous) { listen(); // Don't expect an ack if we're sending an asynchronous ack, but otherwise do // do that we have something to attach a response to, if we're going to get one. // if (!(s.Type == Sendable.ACK) && (c.DuplicateElimination.Equals("always"))) { if (!requests.ContainsKey(s.getMessageId())) requests.Add(s.getMessageId(), s); } } (new Thread(() => this.doTransmission(s))).Start(); }