View Javadoc

1   package ca.uhn.hl7v2.hoh.relay.sender;
2   
3   import java.io.IOException;
4   import java.net.ConnectException;
5   import java.util.Map;
6   
7   import org.springframework.beans.factory.BeanNameAware;
8   import org.springframework.beans.factory.InitializingBean;
9   
10  import ca.uhn.hl7v2.HL7Exception;
11  import ca.uhn.hl7v2.hoh.api.DecodeException;
12  import ca.uhn.hl7v2.hoh.api.EncodeException;
13  import ca.uhn.hl7v2.hoh.api.IReceivable;
14  import ca.uhn.hl7v2.hoh.hapi.api.MessageSendable;
15  import ca.uhn.hl7v2.hoh.hapi.client.HohClientMultithreaded;
16  import ca.uhn.hl7v2.hoh.relay.Binder;
17  import ca.uhn.hl7v2.hoh.util.Validate;
18  import ca.uhn.hl7v2.model.Message;
19  import ca.uhn.hl7v2.protocol.ApplicationRouter;
20  import ca.uhn.hl7v2.protocol.MetadataKeys;
21  import ca.uhn.hl7v2.protocol.ReceivingApplicationException;
22  import ca.uhn.hl7v2.util.Terser;
23  
24  public class RelayHttpSender extends HohClientMultithreaded implements IRelaySender<Message>, BeanNameAware, InitializingBean {
25  
26  	private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RelayHttpSender.class);
27  	private String myBeanName;
28  	private int myIoRetries = 0;
29  	
30  	/**
31  	 * {@inheritDoc}
32  	 */
33  	public void afterPropertiesSet() throws Exception {
34  		Validate.propertySet(getUrl(), "Url");
35  		ourLog.info("Sender [{}] will transmit by HL7 over HTTP to {}", myBeanName, getUrl().toExternalForm());
36  	}
37  
38  	/**
39  	 * Returns true
40  	 * 
41  	 * {@inheritDoc}
42  	 */
43  	public boolean canProcess(Message theMessage) {
44  		return true;
45  	}
46  
47  	/**
48  	 * {@inheritDoc}
49  	 */
50  	public String getBeanName() {
51  		return myBeanName;
52  	}
53  
54  	/**
55  	 * @see #setIoRetries(int)
56  	 */
57  	public int getIoRetries() {
58  		return myIoRetries;
59  	}
60  
61  	/**
62  	 * {@inheritDoc}
63  	 */
64  	public Message processMessage(Message theMessage, Map<String, Object> theMetadata) throws ReceivingApplicationException, HL7Exception {
65  		String sendingIp = (String) theMetadata.get(ApplicationRouter.METADATA_KEY_SENDING_IP);
66  		Object sendingPort = theMetadata.get(ApplicationRouter.METADATA_KEY_SENDING_PORT);
67  		String controlId = (String) theMetadata.get(ApplicationRouter.METADATA_KEY_MESSAGE_CONTROL_ID);
68  		String rawMessage = (String) theMetadata.get(MetadataKeys.IN_RAW_MESSAGE);
69  
70  		ourLog.info("Relaying message ({} bytes) with ID {} from {}:{} to URL {}", new Object[] {rawMessage.length(), controlId, sendingIp, sendingPort, getUrl()});
71  		
72  		IReceivable<Message> response;
73  		long delay = System.currentTimeMillis();
74  		int attempt = -1;
75  		while(true) {
76  			attempt++;
77  			
78  			if (attempt > 0) {
79  				ourLog.info("This is attempt {}", attempt);
80  			}
81  			
82  			try {
83  				response = sendAndReceiveMessage(new MessageSendable(theMessage));
84  				delay = System.currentTimeMillis() - delay;
85  			} catch (DecodeException e) {
86  				ourLog.error("Failed to process HL7 over HTTP response from URL \"" + getUrl().toExternalForm() + "\"", e);
87  				throw new HL7Exception(Binder.getProductname() + " - Failed to process HL7 over HTTP response from URL \"" + getUrl().toExternalForm() + "\" - Error was: " + e.getMessage());
88  			} catch (ConnectException e) {
89  				ourLog.info("Failed to connect to URL \"" + getUrl().toExternalForm() + "\" - Error was: " + e.getMessage());
90  				throw new HL7Exception(Binder.getProductname() + " - Failed to connect to URL \"" + getUrl().toExternalForm() + "\" - Error was: " + e.getMessage());
91  			} catch (IOException e) {
92  				if (attempt < myIoRetries) {
93  					ourLog.warn("Got an IOException, going to retry transmission: " + e.toString());
94  					continue;
95  				}
96  				ourLog.error("IO Exception communicating with URL \"" + getUrl().toExternalForm() + "\"", e);
97  				throw new HL7Exception(Binder.getProductname() + " - IO Exception communicating with URL URL \"" + getUrl().toExternalForm() + "\" - Error was: " + e.getMessage());
98  			} catch (EncodeException e) {
99  				ourLog.error("Failed to create HTTP request", e);
100 				throw new HL7Exception(Binder.getProductname() + " - Failed to create HTTP request - Error was: " + e.getMessage());
101 			}
102 		
103 			break;
104 		}
105 		
106 		String responseControlId = new Terser(response.getMessage()).get("/MSH-10");
107 		ourLog.info("Received response to ID {} with ID {} in {} ms", new Object[] {controlId, responseControlId, delay});
108 		
109 		return response.getMessage();
110 	}
111 
112 	/**
113 	 * <i>Automatically called by the container</i>
114 	 */
115 	public void setBeanName(String theBeanName) {
116 		myBeanName = theBeanName;
117 	}
118 
119 	/**
120 	 * If set to a positive integer, the relay will attempt to redeliver a message up to the given
121 	 * number of times before giving up, if the transmission fails due to an IO exception. 
122 	 */
123 	public void setIoRetries(int theIoRetries) {
124 		myIoRetries = theIoRetries;
125 	}
126 
127 
128 }