/// <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;
		}
예제 #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);
        }
예제 #3
0
        /// <param name="theContext">source of supporting services
        /// </param>
        /// <param name="isThreaded">true if this class should create threads in which to call cycle(), and
        /// in which to send responses from Applications.  This is the preferred mode.  Use false
        /// if threading is not allowed, eg you are running the code in an EJB container.  In this case,
        /// the send() and receive() methods will call cycle() themselves as needed.  However, cycle()
        /// makes potentially blocking calls, so these methods may not return until the next message
        /// is received from the remote server, regardless of timeout.  Probably the worst example of this
        /// would be if receive() was called to wait for an application ACK that was specified as "RE" (ie
        /// required on error).  No response will be returned if the message is processed without error,
        /// and in a non-threaded environment, receive() will block forever.  Use true if you can, otherwise
        /// study this class carefully.
        ///
        /// TODO: write a MLLPTransport with non-blocking IO
        /// TODO: reconnect transport layers on error and retry
        /// </param>
        public NuGenProcessorImpl(NuGenProcessorContext theContext, bool isThreaded)
        {
            myContext           = theContext;
            myThreaded          = isThreaded;
            myAcceptAcks        = new System.Collections.Hashtable();
            myReservations      = new System.Collections.Hashtable();
            myAvailableMessages = new System.Collections.Hashtable();

            if (isThreaded)
            {
                ackCycler = new Cycler(this, true);
                SupportClass.ThreadClass ackThd = new SupportClass.ThreadClass(new System.Threading.ThreadStart(ackCycler.Run));
                ackThd.Start();
                nonAckCycler = new Cycler(this, false);
                SupportClass.ThreadClass nonAckThd = new SupportClass.ThreadClass(new System.Threading.ThreadStart(nonAckCycler.Run));
                nonAckThd.Start();
            }
        }
예제 #4
0
        /// <summary> Accepts a single inbound connection if the same ServerSocket is used for
        /// all message exchanges, or a connection from each if two ServerSockets are
        /// being used.
        ///
        /// </summary>
        /// <param name="theAddress">the IP address from which to accept connections (null means
        /// accept from any address).  Connection attempts from other addresses will
        /// be ignored.
        /// </param>
        /// <returns> a <code>Processor</code> connected to the given address
        /// </returns>
        /// <throws>  TransportException </throws>
        public virtual NuGenProcessor accept(System.String theAddress)
        {
            NuGenTransportLayer   transport = getTransport(myServerSocket, theAddress);
            NuGenProcessorContext context   = null;

            if (myServerSocket2 == null)
            {
                //we're doing inbound & outbound on the same port
                transport.connect();
                context = new NuGenProcessorContextImpl(myRouter, transport, myStorage);
            }
            else
            {
                NuGenTransportLayer         transport2 = getTransport(myServerSocket2, theAddress);
                NuGenDualTransportConnector connector  = new NuGenDualTransportConnector(transport, transport2);
                connector.connect();

                context = new NuGenProcessorContextImpl(myRouter, transport, transport2, myStorage);
            }
            return(new NuGenProcessorImpl(context, true));
        }