private static NuGenTransportable makeAcceptAck(NuGenTransportable theMessage, System.String theAckCode, int theErrorCode, System.String theDescription) { Segment header = ourParser.getCriticalResponseData(theMessage.Message); Message out_Renamed; try { out_Renamed = DefaultApplication.makeACK(header); } catch (System.IO.IOException e) { throw new NuGenHL7Exception(e); } Terser t = new Terser(out_Renamed); t.set_Renamed("/MSA-1", theAckCode); //TODO: when 2.5 is available, use 2.5 fields for remaining problems if (theErrorCode != NuGenHL7Exception.MESSAGE_ACCEPTED) { t.set_Renamed("/MSA-3", theDescription.Substring(0, (System.Math.Min(80, theDescription.Length)) - (0))); t.set_Renamed("/ERR-1-4-1", System.Convert.ToString(theErrorCode)); t.set_Renamed("/ERR-1-4-3", "HL70357"); } System.String originalEncoding = ourParser.getEncoding(theMessage.Message); System.String ackText = ourParser.encode(out_Renamed, originalEncoding); return new NuGenTransportableImpl(ackText); }
/// <summary> Validates the given message against our accept validators, attempts to commit /// the message to safe storage, and returns an ACK message indicating acceptance /// or rejection at the accept level (see enhanced mode processing rules in HL7 /// chapter 2, v2.5). /// </summary> public static AcceptACK validate(NuGenProcessorContext theContext, NuGenTransportable theMessage) { AcceptACK ruling = null; NuGenAcceptValidator[] validators = theContext.Validators; for (int i = 0; i < validators.Length && ruling == null; i++) { Genetibase.NuGenHL7.protocol.AcceptRuling vr = validators[i].check(theMessage); if (!vr.Acceptable) { System.String description = (vr.Reasons.Length > 0)?vr.Reasons[0]:null; NuGenTransportable ack = makeAcceptAck(theMessage, vr.AckCode, vr.ErrorCode, description); ruling = new AcceptACK(false, ack); } } if (ruling == null) { try { theContext.SafeStorage.store(theMessage); NuGenTransportable ack = makeAcceptAck(theMessage, Genetibase.NuGenHL7.protocol.Processor_Fields.CA, NuGenHL7Exception.MESSAGE_ACCEPTED, ""); ruling = new AcceptACK(true, ack); } catch (NuGenHL7Exception e) { int code = NuGenHL7Exception.APPLICATION_INTERNAL_ERROR; NuGenTransportable ack = makeAcceptAck(theMessage, Genetibase.NuGenHL7.protocol.Processor_Fields.CR, code, e.Message); ruling = new AcceptACK(false, ack); } } return(ruling); }
/// <summary> Validates the given message against our accept validators, attempts to commit /// the message to safe storage, and returns an ACK message indicating acceptance /// or rejection at the accept level (see enhanced mode processing rules in HL7 /// chapter 2, v2.5). /// </summary> public static AcceptACK validate(NuGenProcessorContext theContext, NuGenTransportable theMessage) { AcceptACK ruling = null; NuGenAcceptValidator[] validators = theContext.Validators; for (int i = 0; i < validators.Length && ruling == null; i++) { Genetibase.NuGenHL7.protocol.AcceptRuling vr = validators[i].check(theMessage); if (!vr.Acceptable) { System.String description = (vr.Reasons.Length > 0)?vr.Reasons[0]:null; NuGenTransportable ack = makeAcceptAck(theMessage, vr.AckCode, vr.ErrorCode, description); ruling = new AcceptACK(false, ack); } } if (ruling == null) { try { theContext.SafeStorage.store(theMessage); NuGenTransportable ack = makeAcceptAck(theMessage, Genetibase.NuGenHL7.protocol.Processor_Fields.CA, NuGenHL7Exception.MESSAGE_ACCEPTED, ""); ruling = new AcceptACK(true, ack); } catch (NuGenHL7Exception e) { int code = NuGenHL7Exception.APPLICATION_INTERNAL_ERROR; NuGenTransportable ack = makeAcceptAck(theMessage, Genetibase.NuGenHL7.protocol.Processor_Fields.CR, code, e.Message); ruling = new AcceptACK(false, ack); } } return ruling; }
private void cleanReservedMessages() { lock (this) { System.Collections.IEnumerator it = new SupportClass.HashSetSupport(myAvailableMessages.Keys).GetEnumerator(); System.Collections.IList remove = new System.Collections.ArrayList(); while (it.MoveNext()) { System.String ackId = (System.String)it.Current; ExpiringTransportable et = (ExpiringTransportable)myAvailableMessages[ackId]; if ((System.DateTime.Now.Ticks - 621355968000000000) / 10000 > et.expiryTime) { //myAvailableMessages.Remove(it.Current); remove.Add(it.Current); //send to an Application NuGenTransportable out_Renamed = myContext.Router.processMessage(et.transportable); sendAppResponse(out_Renamed); } foreach (object item in remove) { myAvailableMessages.Remove(item); } } } }
/// <seealso cref="Genetibase.NuGenHL7.protocol.Processor.receive(java.lang.String, long)"> /// </seealso> public virtual NuGenTransportable receive(System.String theAckId, long theTimeoutMillis) { if (!isReserved(theAckId)) { reserve(theAckId, theTimeoutMillis); } NuGenTransportable in_Renamed = null; long until = (System.DateTime.Now.Ticks - 621355968000000000) / 10000 + theTimeoutMillis; do { lock (this) { ExpiringTransportable et = (ExpiringTransportable)myAvailableMessages[theAckId]; if (et == null) { cycleIfNeeded(false); } else { in_Renamed = et.transportable; } } sleepIfNeeded(); }while (in_Renamed == null && (System.DateTime.Now.Ticks - 621355968000000000) / 10000 < until); return(in_Renamed); }
private static NuGenTransportable makeAcceptAck(NuGenTransportable theMessage, System.String theAckCode, int theErrorCode, System.String theDescription) { Segment header = ourParser.getCriticalResponseData(theMessage.Message); Message out_Renamed; try { out_Renamed = DefaultApplication.makeACK(header); } catch (System.IO.IOException e) { throw new NuGenHL7Exception(e); } Terser t = new Terser(out_Renamed); t.set_Renamed("/MSA-1", theAckCode); //TODO: when 2.5 is available, use 2.5 fields for remaining problems if (theErrorCode != NuGenHL7Exception.MESSAGE_ACCEPTED) { t.set_Renamed("/MSA-3", theDescription.Substring(0, (System.Math.Min(80, theDescription.Length)) - (0))); t.set_Renamed("/ERR-1-4-1", System.Convert.ToString(theErrorCode)); t.set_Renamed("/ERR-1-4-3", "HL70357"); } System.String originalEncoding = ourParser.getEncoding(theMessage.Message); System.String ackText = ourParser.encode(out_Renamed, originalEncoding); return(new NuGenTransportableImpl(ackText)); }
/// <seealso cref="Genetibase.NuGenHL7.protocol.Initiator.sendAndReceive(Genetibase.NuGenHL7.model.Message)"> /// </seealso> public virtual Message sendAndReceive(Message theMessage) { Terser t = new Terser(theMessage); System.String appAckNeeded = t.get_Renamed("/MSH-16"); System.String msgId = t.get_Renamed("/MSH-10"); System.String messageText = Parser.encode(theMessage); System.Collections.IDictionary metadata = getMetadata(theMessage); NuGenTransportable out_Renamed = new NuGenTransportableImpl(messageText, metadata); if (needAck(appAckNeeded)) { myProcessor.reserve(msgId, ReceiveTimeout); } myProcessor.send(out_Renamed, MaxRetries, RetryInterval); Message in_Renamed = null; if (needAck(appAckNeeded)) { NuGenTransportable received = myProcessor.receive(msgId, ReceiveTimeout); if (received != null && received.Message != null) { in_Renamed = Parser.parse(received.Message); } } return(in_Renamed); }
/// <summary> Delegates to <code>doSend()</code> after checking that we are connected. /// /// </summary> /// <seealso cref="Genetibase.NuGenHL7.protocol.TransportLayer.send(Transportable)"> /// </seealso> public virtual void send(NuGenTransportable theMessage) { if (!Connected) { throw new NuGenTransportException("Can't send because TransportLayer is not connected"); } doSend(theMessage); }
/// <seealso cref="Genetibase.NuGenHL7.protocol.Processor.send(Genetibase.NuGenHL7.protocol.Transportable, int, long)"> /// </seealso> public virtual void send(NuGenTransportable theMessage, int maxRetries, long retryIntervalMillis) { System.String[] fieldPaths = new System.String[] { "MSH-10", "MSH-15", "MSH-16" }; System.String[] fields = PreParser.getFields(theMessage.Message, fieldPaths); System.String controlId = fields[0]; System.String needAcceptAck = fields[1]; System.String needAppAck = fields[2]; checkValidAckNeededCode(needAcceptAck); trySend(myContext.LocallyDrivenTransportLayer, theMessage); bool originalMode = (needAcceptAck == null && needAppAck == null); if (originalMode || !needAcceptAck.Equals(Genetibase.NuGenHL7.protocol.Processor_Fields.NE)) { NuGenTransportable response = null; int retries = 0; do { long until = (System.DateTime.Now.Ticks - 621355968000000000) / 10000 + retryIntervalMillis; while (response == null && (System.DateTime.Now.Ticks - 621355968000000000) / 10000 < until) { lock (this) { System.Object tempObject; tempObject = myAcceptAcks[controlId]; myAcceptAcks.Remove(controlId); ExpiringTransportable et = (ExpiringTransportable)tempObject; if (et == null) { cycleIfNeeded(true); } else { response = et.transportable; } } sleepIfNeeded(); } if ((response == null && needAcceptAck != null && needAcceptAck.Equals(Genetibase.NuGenHL7.protocol.Processor_Fields.AL)) || (response != null && isReject(response))) { trySend(myContext.LocallyDrivenTransportLayer, theMessage); response = null; } if (response != null && isError(response)) { System.String[] errMsgPath = new System.String[] { "MSA-3" }; System.String[] errMsg = PreParser.getFields(response.Message, errMsgPath); throw new NuGenHL7Exception("Error message received: " + errMsg[0]); } }while (response == null && ++retries <= maxRetries); } }
/// <seealso cref="Genetibase.NuGenHL7.protocol.ApplicationRouter.processMessage(Genetibase.NuGenHL7.protocol.Transportable)"> /// </seealso> public virtual NuGenTransportable processMessage(NuGenTransportable theMessage) { System.String[] result = processMessage(theMessage.Message, theMessage.Metadata); NuGenTransportable response = new NuGenTransportableImpl(result[0]); if (result[1] != null) { response.Metadata["MSH-18"] = result[1]; } return(response); }
/// <summary>Returns true if a CE or AE ACK </summary> private static bool isError(NuGenTransportable theMessage) { bool error = false; System.String[] fieldPaths = new System.String[] { "MSA-1" }; System.String[] fields = PreParser.getFields(theMessage.Message, fieldPaths); if (fields[0] != null && (fields[0].Equals(Genetibase.NuGenHL7.protocol.Processor_Fields.CE) || fields[0].Equals(Genetibase.NuGenHL7.protocol.Processor_Fields.AE))) { error = true; } return(error); }
/// <seealso cref="Genetibase.NuGenHL7.protocol.ApplicationRouter.processMessage(Genetibase.NuGenHL7.protocol.Transportable)"> /// </seealso> public virtual NuGenTransportable processMessage(NuGenTransportable theMessage) { System.String[] result = processMessage(theMessage.Message, theMessage.Metadata); NuGenTransportable response = new NuGenTransportableImpl(result[0]); if (result[1] != null) { response.Metadata["MSH-18"] = result[1]; } return response; }
/// <summary> Tries to send the message, and if there is an error reconnects and tries again. </summary> private void trySend(NuGenTransportLayer theTransport, NuGenTransportable theTransportable) { try { theTransport.send(theTransportable); } catch (NuGenTransportException) { theTransport.disconnect(); theTransport.connect(); theTransport.send(theTransportable); } }
/// <summary>Sends in a new thread if isThreaded, otherwise in current thread </summary> private void sendAppResponse(NuGenTransportable theResponse) { NuGenProcessorImpl processor = this; IThreadRunnable sender = new AnonymousClassRunnable(processor, theResponse, this); if (myThreaded) { SupportClass.ThreadClass thd = new SupportClass.ThreadClass(new System.Threading.ThreadStart(sender.Run)); thd.Start(); } else { sender.Run(); } }
/// <summary> Tries to receive a message, and if there is an error reconnects and tries again. </summary> private NuGenTransportable tryReceive(NuGenTransportLayer theTransport) { NuGenTransportable message = null; try { message = theTransport.receive(); } catch (NuGenTransportException) { theTransport.disconnect(); theTransport.connect(); message = theTransport.receive(); } return(message); }
/// <summary> Delegates to <code>doReceive()</code> and adds common metadata /// to the resulting <code>Transportable</code> before it is returned. /// </summary> public virtual NuGenTransportable receive() { if (!Connected) { throw new NuGenTransportException("Can't receive because TransportLayer is not connected"); } NuGenTransportable message = doReceive(); if (message != null) { SupportClass.MapSupport.PutAll(message.Metadata, myCommonMetadata); } return(message); }
/// <summary> Writes the given message to the URL. /// /// </summary> /// <param name="theMessage">the message to send /// </param> /// <seealso cref="Genetibase.NuGenHL7.protocol.AbstractTransport.doSend(Genetibase.NuGenHL7.protocol.Transportable)"> /// </seealso> public override void doSend(NuGenTransportable theMessage) { if (myConnectOnSend) { makeConnection(); } try { System.IO.StreamWriter out_Renamed = new System.IO.StreamWriter(new System.IO.BufferedStream(myConnection.GetRequestStream()), System.Text.Encoding.Default); out_Renamed.Write(theMessage.Message); out_Renamed.Flush(); } catch (System.IO.IOException e) { throw new NuGenTransportException(e); } }
/// <seealso cref="Genetibase.NuGenHL7.protocol.impl.AbstractTransport.doReceive()"> /// </seealso> public override NuGenTransportable doReceive() { NuGenTransportable result = null; try { System.String message = myReader.getMessage(); if (message != null) { result = new NuGenTransportableImpl(message); } } catch (LLPException e) { throw new NuGenTransportException(e); } catch (System.IO.IOException e) { throw new NuGenTransportException(e); } return(result); }
/// <seealso cref="Genetibase.NuGenHL7.protocol.AstractTransport.doSend(Genetibase.NuGenHL7.protocol.Transportable)"> /// </seealso> public override void doSend(NuGenTransportable theMessage) { try { System.String charset = (System.String)theMessage.Metadata["MSH-18"]; if (charset != null) { charset = myCharsetMappings[charset] == null?charset:myCharsetMappings[charset]; //default to self if no match myWriter.writeMessage(theMessage.Message, charset); } else { myWriter.writeMessage(theMessage.Message); } } catch (LLPException e) { throw new NuGenTransportException(e); } catch (System.IO.IOException e) { throw new NuGenTransportException(e); } }
/// <summary> The method send() delegates to this method after checking whether we are /// connected. /// </summary> /// <param name="theMessage"> /// </param> /// <throws> TransportException </throws> public abstract void doSend(NuGenTransportable theMessage);
/// <seealso cref="Genetibase.NuGenHL7.protocol.Processor.cycle(boolean)"> /// </seealso> public virtual void cycle(bool expectingAck) { cleanReservations(); cleanAcceptAcks(); cleanReservedMessages(); NuGenTransportable in_Renamed = null; try { if (expectingAck) { in_Renamed = tryReceive(myContext.LocallyDrivenTransportLayer); } else { in_Renamed = tryReceive(myContext.RemotelyDrivenTransportLayer); } } catch (NuGenTransportException e) { try { System.Threading.Thread.Sleep(new System.TimeSpan((System.Int64) 10000 * 1000)); } catch (System.Threading.ThreadInterruptedException) { } throw e; } if (in_Renamed != null) { System.String[] fieldPaths = new System.String[] { "MSH-15", "MSH-16", "MSA-1", "MSA-2" }; System.String[] fields = PreParser.getFields(in_Renamed.Message, fieldPaths); System.String acceptAckNeeded = fields[0]; System.String appAckNeeded = fields[1]; System.String ackCode = fields[2]; System.String ackId = fields[3]; if (ackId != null && ackCode != null && ackCode.StartsWith("C")) { long expiryTime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000 + 1000 * 60; myAcceptAcks[ackId] = new ExpiringTransportable(this, in_Renamed, expiryTime); } else { NuGenAcceptAcknowledger.AcceptACK ack = NuGenAcceptAcknowledger.validate(Context, in_Renamed); if ((acceptAckNeeded != null && acceptAckNeeded.Equals(Genetibase.NuGenHL7.protocol.Processor_Fields.AL)) || (acceptAckNeeded != null && acceptAckNeeded.Equals(Genetibase.NuGenHL7.protocol.Processor_Fields.ER) && !ack.Acceptable) || (acceptAckNeeded != null && acceptAckNeeded.Equals(Genetibase.NuGenHL7.protocol.Processor_Fields.SU) && ack.Acceptable)) { trySend(myContext.RemotelyDrivenTransportLayer, ack.Message); } if (ack.Acceptable) { if (isReserved(ackId)) { removeReservation(ackId); long expiryTime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000 + 1000 * 60 * 5; myAvailableMessages[ackId] = new ExpiringTransportable(this, in_Renamed, expiryTime); } else { NuGenTransportable out_Renamed = myContext.Router.processMessage(in_Renamed); sendAppResponse(out_Renamed); } } } } else { System.String transport = expectingAck?" Locally driven ":"Remotely driven"; } sleepIfNeeded(); }
public ExpiringTransportable(NuGenProcessorImpl enclosingInstance, NuGenTransportable theTransportable, long theExpiryTime) { InitBlock(enclosingInstance); transportable = theTransportable; expiryTime = theExpiryTime; }
/// <summary> Does nothing. </summary> public virtual void store(NuGenTransportable theMessage) { }
public AcceptACK(bool isAcceptable, NuGenTransportable theAck) { myIsAcceptable = isAcceptable; myAck = theAck; }
/// <summary> Does nothing. </summary> public virtual void discard(NuGenTransportable theMessage) { }