001package ca.uhn.hl7v2.hoh.raw.server; 002 003import java.io.IOException; 004import java.nio.charset.Charset; 005import java.util.Enumeration; 006import java.util.LinkedHashMap; 007 008import javax.servlet.ServletException; 009import javax.servlet.http.HttpServlet; 010import javax.servlet.http.HttpServletRequest; 011import javax.servlet.http.HttpServletResponse; 012 013import ca.uhn.hl7v2.hoh.api.DecodeException; 014import ca.uhn.hl7v2.hoh.api.IAuthorizationServerCallback; 015import ca.uhn.hl7v2.hoh.api.IMessageHandler; 016import ca.uhn.hl7v2.hoh.api.IResponseSendable; 017import ca.uhn.hl7v2.hoh.api.MessageMetadataKeys; 018import ca.uhn.hl7v2.hoh.api.MessageProcessingException; 019import ca.uhn.hl7v2.hoh.encoder.AuthorizationFailureException; 020import ca.uhn.hl7v2.hoh.encoder.Hl7OverHttpRequestDecoder; 021import ca.uhn.hl7v2.hoh.raw.api.RawReceivable; 022import ca.uhn.hl7v2.hoh.sign.ISigner; 023import ca.uhn.hl7v2.hoh.sign.SignatureVerificationException; 024import ca.uhn.hl7v2.hoh.util.HTTPUtils; 025 026public class HohRawServlet extends HttpServlet { 027 028 private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(HohRawServlet.class); 029 private static final long serialVersionUID = 1L; 030 private IAuthorizationServerCallback myAuthorizationCallback; 031 private IMessageHandler<String> myMessageHandler; 032 private ISigner mySigner; 033 034 /** 035 * {@inheritDoc} 036 */ 037 @Override 038 protected void doGet(HttpServletRequest theReq, HttpServletResponse theResp) throws ServletException, IOException { 039 040 theResp.setStatus(400); 041 theResp.setContentType("text/html"); 042 043 String message = "GET method is not supported by this server"; 044 HTTPUtils.write400BadRequest(theResp.getOutputStream(), message, false); 045 046 } 047 048 /** 049 * {@inheritDoc} 050 */ 051 @Override 052 protected void doPost(HttpServletRequest theReq, HttpServletResponse theResp) throws ServletException, IOException { 053 054 Hl7OverHttpRequestDecoder decoder = new Hl7OverHttpRequestDecoder(); 055 decoder.setHeaders(new LinkedHashMap<String, String>()); 056 057 Enumeration<?> headerNames = theReq.getHeaderNames(); 058 while (headerNames.hasMoreElements()) { 059 String nextName = (String) headerNames.nextElement(); 060 decoder.getHeaders().put(nextName, theReq.getHeader(nextName)); 061 } 062 063 decoder.setPath(theReq.getRequestURI()); 064 decoder.setAuthorizationCallback(myAuthorizationCallback); 065 decoder.setSigner(mySigner); 066 067 try { 068 decoder.readContentsFromInputStreamAndDecode(theReq.getInputStream()); 069 } catch (AuthorizationFailureException e) { 070 ourLog.error("Authorization failed on request for {}", theReq.getRequestURI()); 071 theResp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 072 HTTPUtils.write401Unauthorized(theResp.getOutputStream(), false); 073 return; 074 } catch (DecodeException e) { 075 ourLog.error("Request failure for " + theReq.getRequestURI(), e); 076 theResp.setStatus(HttpServletResponse.SC_BAD_REQUEST); 077 HTTPUtils.write400BadRequest(theResp.getOutputStream(), e.getMessage(), false); 078 return; 079 } catch (SignatureVerificationException e) { 080 ourLog.error("Signature verification failed on request for {}", theReq.getRequestURI()); 081 theResp.setStatus(HttpServletResponse.SC_BAD_REQUEST); 082 HTTPUtils.write400SignatureVerificationFailed(theResp.getOutputStream(), false); 083 return; 084 } 085 086 Charset charset = decoder.getCharset(); 087 ourLog.debug("Message charset is {}", charset.displayName()); 088 089 RawReceivable rawMessage = new RawReceivable(decoder.getMessage()); 090 rawMessage.addMetadata(MessageMetadataKeys.REMOTE_HOST_ADDRESS.name(), theReq.getRemoteAddr()); 091 092 IResponseSendable<String> response; 093 try { 094 response = myMessageHandler.messageReceived(rawMessage); 095 } catch (MessageProcessingException e) { 096 ourLog.error("Processing problem for " + theReq.getRequestURI(), e); 097 theResp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 098 HTTPUtils.write500InternalServerError(theResp.getOutputStream(), e.getMessage(), false); 099 return; 100 } 101 102 theResp.setCharacterEncoding(charset.name()); 103 theResp.setContentType(response.getEncodingStyle().getContentType()); 104 theResp.setStatus(response.getResponseCode().getCode()); 105 106 // n.b. don't ask for the writer until headers are set 107 response.writeMessage(theResp.getWriter()); 108 theResp.flushBuffer(); 109 110 } 111 112 /** 113 * If set, provides a callback which will be used to validate incoming 114 * credentials 115 */ 116 public void setAuthorizationCallback(IAuthorizationServerCallback theAuthorizationCallback) { 117 myAuthorizationCallback = theAuthorizationCallback; 118 } 119 120 /** 121 * @param theMessageHandler 122 * the messageHandler to set 123 */ 124 public void setMessageHandler(IMessageHandler<String> theMessageHandler) { 125 myMessageHandler = theMessageHandler; 126 } 127 128 /** 129 * Sets the message signer if signature profile is being used 130 */ 131 public void setSigner(ISigner theSigner) { 132 mySigner = theSigner; 133 } 134 135}