View Javadoc
1   package ca.uhn.hl7v2.hoh.raw.server;
2   
3   import java.io.IOException;
4   import java.nio.charset.Charset;
5   import java.util.Enumeration;
6   import java.util.LinkedHashMap;
7   
8   import ca.uhn.hl7v2.hoh.api.DecodeException;
9   import ca.uhn.hl7v2.hoh.api.IAuthorizationServerCallback;
10  import ca.uhn.hl7v2.hoh.api.IMessageHandler;
11  import ca.uhn.hl7v2.hoh.api.IResponseSendable;
12  import ca.uhn.hl7v2.hoh.api.MessageMetadataKeys;
13  import ca.uhn.hl7v2.hoh.api.MessageProcessingException;
14  import ca.uhn.hl7v2.hoh.encoder.AuthorizationFailureException;
15  import ca.uhn.hl7v2.hoh.encoder.Hl7OverHttpRequestDecoder;
16  import ca.uhn.hl7v2.hoh.raw.api.RawReceivable;
17  import ca.uhn.hl7v2.hoh.sign.ISigner;
18  import ca.uhn.hl7v2.hoh.sign.SignatureVerificationException;
19  import ca.uhn.hl7v2.hoh.util.HTTPUtils;
20  import jakarta.servlet.http.HttpServlet;
21  import jakarta.servlet.http.HttpServletRequest;
22  import jakarta.servlet.http.HttpServletResponse;
23  
24  public class HohRawServlet extends HttpServlet {
25  
26  	private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(HohRawServlet.class);
27  	private static final long serialVersionUID = 1L;
28  	private IAuthorizationServerCallback myAuthorizationCallback;
29  	private IMessageHandler<String> myMessageHandler;
30  	private ISigner mySigner;
31  
32  	/**
33  	 * {@inheritDoc}
34  	 */
35  	@Override
36  	protected void doGet(HttpServletRequest theReq, HttpServletResponse theResp) throws IOException {
37  
38  		theResp.setStatus(400);
39  		theResp.setContentType("text/html");
40  
41  		String message = "GET method is not supported by this server";
42  		HTTPUtils.write400BadRequest(theResp.getOutputStream(), message, false);
43  
44  	}
45  
46  	/**
47  	 * {@inheritDoc}
48  	 */
49  	@Override
50  	protected void doPost(HttpServletRequest theReq, HttpServletResponse theResp) throws IOException {
51  
52  		Hl7OverHttpRequestDecoder decoder = new Hl7OverHttpRequestDecoder();
53  		decoder.setHeaders(new LinkedHashMap<>());
54  
55  		Enumeration<?> headerNames = theReq.getHeaderNames();
56  		while (headerNames.hasMoreElements()) {
57  			String nextName = (String) headerNames.nextElement();
58  			decoder.getHeaders().put(nextName, theReq.getHeader(nextName));
59  		}
60  
61  		decoder.setPath(theReq.getRequestURI());
62  		decoder.setAuthorizationCallback(myAuthorizationCallback);
63  		decoder.setSigner(mySigner);
64  
65  		try {
66  			decoder.readContentsFromInputStreamAndDecode(theReq.getInputStream());
67  		} catch (AuthorizationFailureException e) {
68  			ourLog.error("Authorization failed on request for {}", theReq.getRequestURI());
69  			theResp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
70  			HTTPUtils.write401Unauthorized(theResp.getOutputStream(), false);
71  			return;
72  		} catch (DecodeException e) {
73  			ourLog.error("Request failure for " + theReq.getRequestURI(), e);
74  			theResp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
75  			HTTPUtils.write400BadRequest(theResp.getOutputStream(), e.getMessage(), false);
76  			return;
77  		} catch (SignatureVerificationException e) {
78  			ourLog.error("Signature verification failed on request for {}", theReq.getRequestURI());
79  			theResp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
80  			HTTPUtils.write400SignatureVerificationFailed(theResp.getOutputStream(), false);
81  			return;
82  		}
83  
84  		Charset charset = decoder.getCharset();
85  		ourLog.debug("Message charset is {}", charset.displayName());
86  
87  		RawReceivable rawMessage = new RawReceivable(decoder.getMessage());
88  		rawMessage.addMetadata(MessageMetadataKeys.REMOTE_HOST_ADDRESS.name(), theReq.getRemoteAddr());
89  
90  		IResponseSendable<String> response;
91  		try {
92  			response = myMessageHandler.messageReceived(rawMessage);
93  		} catch (MessageProcessingException e) {
94  			ourLog.error("Processing problem for " + theReq.getRequestURI(), e);
95  			theResp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
96  			HTTPUtils.write500InternalServerError(theResp.getOutputStream(), e.getMessage(), false);
97  			return;
98  		}
99  
100 		theResp.setCharacterEncoding(charset.name());
101 		theResp.setContentType(response.getEncodingStyle().getContentType());
102 		theResp.setStatus(response.getResponseCode().getCode());
103 
104 		// n.b. don't ask for the writer until headers are set
105 		response.writeMessage(theResp.getWriter());
106 		theResp.flushBuffer();
107 
108 	}
109 
110 	/**
111 	 * If set, provides a callback which will be used to validate incoming
112 	 * credentials
113 	 */
114 	public void setAuthorizationCallback(IAuthorizationServerCallback theAuthorizationCallback) {
115 		myAuthorizationCallback = theAuthorizationCallback;
116 	}
117 
118 	/**
119 	 * @param theMessageHandler
120 	 *            the messageHandler to set
121 	 */
122 	public void setMessageHandler(IMessageHandler<String> theMessageHandler) {
123 		myMessageHandler = theMessageHandler;
124 	}
125 
126 	/**
127 	 * Sets the message signer if signature profile is being used
128 	 */
129 	public void setSigner(ISigner theSigner) {
130 		mySigner = theSigner;
131 	}
132 
133 }