001/*
002 * Created on 16-Apr-2004
003 */
004package ca.uhn.hl7v2.protocol;
005
006import ca.uhn.hl7v2.HL7Exception;
007
008/**
009 * Encapsulates both the client and server roles of the HL7-defined 
010 * "original mode" and "enhanced mode" processing rules.  See 
011 * HL7 v2.5 chapter 2 for specifications.    
012 *  
013 * @author <a href="mailto:bryan.tripp@uhn.on.ca">Bryan Tripp</a>
014 * @version $Revision: 1.1 $ updated on $Date: 2007-02-19 02:24:38 $ by $Author: jamesagnew $
015 */
016public interface Processor {
017    
018    /**
019     * Always send acknowledgement (in MSH-15 and 16)
020     */
021    public static final String AL = "AL";
022    
023    /**
024     * Never send acknowledgement (in MSH-15 and 16)
025     */
026    public static final String NE = "NE";
027
028    /**
029     * Send acknowledgement only on error / reject (in MSH-15 and 16)
030     */
031    public static final String ER = "ER";
032    
033    /**
034     * Send acknowledgement only on successful receipt (in MSH-15 and 16)
035     */
036    public static final String SU = "SU";
037        
038    
039    /**
040     * Original mode: Application Accept - Enhanced mode: Application acknowledgment: Accept
041     */
042    public static final String AA = "AA"; 
043    
044    /**
045     * Original mode: Application Error - Enhanced mode: Application acknowledgment: Error 
046     */
047    public static final String AE = "AE"; 
048    /**
049     * Original mode: Application Reject - Enhanced mode: Application acknowledgment: Reject
050     */
051    public static final String AR = "AR";
052    
053    /**
054     * Enhanced mode: Accept acknowledgment: Commit Accept
055     */
056    public static final String CA = "CA"; 
057    
058    /**
059     * Enhanced mode: Accept acknow ledgment: Commit Error
060     */
061    public static final String CE = "CE";
062    
063    /**
064     * Enhanced mode: Accept acknowledgment: Commit Reject
065     */
066    public static final String CR = "CR";
067    
068    
069    /**
070     * Sends a message to a remote system via an underlying 
071     * <code>TransportLayer</code>.  
072     * 
073     * If the message specifies that an accept ACK is required (under enhanced mode 
074     * processing rules) then this method may retry if transmission does not appear 
075     * to be successful.  The call to this method blocks while this is happening.  
076     * Retries are attempted if a CR message is received, or if no message is received
077     * in the specified time frame.  If a CE is received, an exception is thrown.  If 
078     * a CA is received, the call returns quietly.  
079     * 
080     * If no accept ack is required, this method returns immediately after attempting to 
081     * send a message, throwing an exception only if there is an immediate problem (eg the
082     * server can't be contacted).  
083     * 
084     * If an accept ack is required only on error, the method waits for maxRetries * 
085     * retryItervalMillis for an error to be returned, and assumes that there is no error
086     * if none appears in that time.  The message is not actually resent while waiting for an 
087     * error ACK. 
088     * 
089     * @param theMessage the message to send 
090     * @param maxRetries note that this should be a small value if you demand an accept ack only
091     *      on error
092     * @param retryIntervalMillis note that this should be a small value if you demand an accept ack only
093     *      on error
094     * @throws TransportException if there is an immediate problem trying to send the 
095     *      message.  
096     */
097    public void send(Transportable theMessage, int maxRetries, long retryIntervalMillis) throws HL7Exception;
098    
099    /**
100     * Indicates that the calling thread expects a message with a certain ack
101     * ID.  If this message arrives within the specified period of time, it will 
102     * be held in an inbound list instead of being passed on to an 
103     * <code>Application</code>.  If a message is in this list it <code>isAvailable()</code>
104     * and can be had via <code>receive()</code>
105     * 
106     * @param theAckId the acknowledgement ID of the message 
107     * @param thePeriodMillis time span during which the message should be kept if received
108     */
109    public void reserve(String theAckId, long thePeriodMillis);
110    
111    /**
112     * <p>Performs a single iteration of the receiving-side 
113     * of the HL7 original mode or enhanced mode processing rules
114     * (see HL7 Standard v2.5 Chapter 2; the choice of rules
115     * is determined by message values).  Steps in the process are 
116     * as follows: </p>
117     * 
118     * 1. TransportLayer.receive() is called to get the next message <br> 
119     * 2. Validation is performed and the message is stored locally. <br>
120     * 2. If the message requires an accept ACK, then an accept, reject, 
121     *   or error message is returned as appropriate  <br>
122     * 3. If the message is an accept ack, it is added to a local list that 
123     * can be accessed by the send() method <br>
124     * 4. If the message has been reserved, it is added to the available message
125     * list.  <br>
126     * 5. Otherwise it is sent to an Application.   
127     * 
128     * @param expectingAck is passed to TransportLayer.receive(), and may determine 
129     *      where the message is read from (eg different sockets may be used for 
130     *      commit-level ACKs).  Note that this call blocks until a message is ready
131     *      at the specified location, so to run the Processor continuously,  
132     *      separate threads are needed to call cycle() with true and false args.   
133     */
134    public void cycle(boolean expectingAck) throws HL7Exception; 
135        
136    /**
137     * @param theAckId the acknowledgement ID of an expected message 
138     * @return true if the message has come in and has been saved in the 
139     *      inbound message list 
140     */
141    public boolean isAvailable(String theAckId);
142    
143    /**
144     * Gets the message with the given acknowledgement ID from 
145     * the incoming message list.  This method blocks until the 
146     * message appears on the list.  If you don't want to block, 
147     * call <code>isAvailable()</code> to see if it is there.
148     * 
149     * Note also that the message has no way of arriving on the list 
150     * during this call unless the <code>Processor</code> is running 
151     * as a thread, or unless some other thread is calling cycle().   
152     *      
153     * @param theAckId
154     * @param theTimeoutMillis milliseconds until the call times out
155     *      and returns null if the desired message is not available. 
156     * @return the incoming message with the given ack ID, or null 
157     *      if the call times out. 
158     */
159    public Transportable receive(String theAckId, long theTimeoutMillis) throws HL7Exception;
160    
161    /**
162     * @return the operational context of this protocol instance 
163     */
164    public ProcessorContext getContext();
165
166    /**
167     * Request that the processor stop running and clean up any resources and worker threads it has started
168     */
169    public void stop();
170
171    
172}