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);
		}
Beispiel #2
0
        /// <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;
		}
Beispiel #4
0
        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);
                    }
                }
            }
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        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));
        }
Beispiel #7
0
        /// <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);
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #9
0
        /// <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);
        }
Beispiel #11
0
        /// <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;
		}
Beispiel #13
0
 /// <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);
     }
 }
Beispiel #14
0
        /// <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();
            }
        }
Beispiel #15
0
        /// <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);
        }
Beispiel #16
0
        /// <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);
        }
Beispiel #17
0
        /// <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);
     }
 }
Beispiel #20
0
 /// <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);
Beispiel #21
0
        /// <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();
        }
Beispiel #22
0
 public ExpiringTransportable(NuGenProcessorImpl enclosingInstance, NuGenTransportable theTransportable, long theExpiryTime)
 {
     InitBlock(enclosingInstance);
     transportable = theTransportable;
     expiryTime    = theExpiryTime;
 }
Beispiel #23
0
 /// <summary> Does nothing. </summary>
 public virtual void  store(NuGenTransportable theMessage)
 {
 }
			public AcceptACK(bool isAcceptable, NuGenTransportable theAck)
			{
				myIsAcceptable = isAcceptable;
				myAck = theAck;
			}
Beispiel #25
0
 /// <summary> Does nothing. </summary>
 public virtual void  discard(NuGenTransportable theMessage)
 {
 }
Beispiel #26
0
 public AcceptACK(bool isAcceptable, NuGenTransportable theAck)
 {
     myIsAcceptable = isAcceptable;
     myAck          = theAck;
 }