/* * Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.wso2.carbon.business.messaging.hl7.transport; import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.soap.SOAPEnvelope; import org.apache.axiom.soap.SOAPFactory; import org.apache.axis2.AxisFault; import org.apache.axis2.context.MessageContext; import org.apache.axis2.engine.AxisEngine; import org.apache.axis2.transport.OutTransportInfo; import org.apache.axis2.transport.base.AbstractTransportSender; import org.wso2.carbon.business.messaging.hl7.common.HL7Constants; import org.wso2.carbon.business.messaging.hl7.common.HL7ProcessingContext; import org.wso2.carbon.business.messaging.hl7.common.HL7Utils; import ca.uhn.hl7v2.HL7Exception; import ca.uhn.hl7v2.app.Connection; import ca.uhn.hl7v2.app.ConnectionHub; import ca.uhn.hl7v2.app.Initiator; import ca.uhn.hl7v2.llp.MinLowerLayerProtocol; import ca.uhn.hl7v2.model.Message; import ca.uhn.hl7v2.parser.DefaultXMLParser; import ca.uhn.hl7v2.parser.Parser; import ca.uhn.hl7v2.parser.PipeParser; import ca.uhn.hl7v2.validation.impl.NoValidation; public class HL7TransportSender extends AbstractTransportSender { private Parser xmlparser; public HL7TransportSender() { xmlparser = new DefaultXMLParser(); xmlparser.setValidationContext(new NoValidation()); } @Override public void sendMessage(MessageContext messageContext, String targetEPR, OutTransportInfo outTransportInfo) throws AxisFault { if (targetEPR != null) { // Forward the message to the given EPR sendUsingEPR(messageContext, targetEPR); } else { // Send the application ack message back to the client sendApplicationACKResponse(messageContext, outTransportInfo); } } private void processResponse(Message returnMsg, MessageContext messageContext) throws AxisFault { try { MessageContext rmc = createResponseMessageContext(messageContext); SOAPEnvelope soapEnvelope = createEnvelope(returnMsg); rmc.setEnvelope(soapEnvelope); AxisEngine.receive(rmc); } catch (Exception e) { handleException("Error while processing the response HL7 message", e); } } private Connection getConnection(String targetEPR, ConnectionHub hub) throws AxisFault { try { URI url = new URI(targetEPR); String targetHost = url.getHost(); int targetPort = url.getPort(); return hub.attach(targetHost, targetPort, new PipeParser(), MinLowerLayerProtocol.class); } catch (URISyntaxException e) { handleException("Malformed HL7 URI syntax: " + targetEPR, e); } catch (HL7Exception e) { handleException("Error while obtaining HL7 connection to: " + targetEPR, e); } return null; } private Map<String,String> getURLParameters(String url) throws AxisFault { try { Map<String,String> params = new HashMap<String,String>(); URI hl7Url = new URI(url); String query = hl7Url.getQuery(); if (query != null) { String[] paramStrings = query.split("&"); for (String p : paramStrings) { int index = p.indexOf('='); params.put(p.substring(0, index), p.substring(index+1)); } } return params; } catch (URISyntaxException e) { handleException("Malformed HL7 url", e); } return null; } private SOAPEnvelope createEnvelope(Message message) throws HL7Exception, XMLStreamException { SOAPFactory fac = OMAbstractFactory.getSOAP11Factory(); SOAPEnvelope envelope = fac.getDefaultEnvelope(); OMElement messageEl = HL7Utils.generateHL7MessageElement(this.xmlparser.encode(message)); envelope.getBody().addChild(messageEl); return envelope; } private void sendUsingEPR(MessageContext messageContext, String targetEPR) throws AxisFault { if (log.isDebugEnabled()) { log.debug("Send HL7 message using EPR :" + targetEPR); } OMElement omElement = messageContext.getEnvelope().getBody().getFirstElement() .getFirstElement(); String xmlFormat = omElement.toString(); Message returnMsg = null; Map<String, String> params = getURLParameters(targetEPR); try { Message message; Boolean isValid = (Boolean) messageContext.getProperty(HL7Constants.HL7_VALIDATION_PASSED); if((isValid != null && !isValid) && messageContext.getProperty(HL7Constants.HL7_PASS_THROUGH_INVALID_MESSAGES).equals(true)) { // pass through invalid messages message = (Message) messageContext.getProperty(HL7Constants.HL7_MESSAGE_OBJECT); } else { message = xmlparser.parse(xmlFormat); } ConnectionHub connectionHub = ConnectionHub.getInstance(); Connection connection = getConnection(targetEPR, connectionHub); Initiator initiator = connection.getInitiator(); String timeout = params.get(HL7Constants.TIMEOUT_PARAM); if (timeout != null) { initiator.setTimeoutMillis(Integer.parseInt(timeout)); } else { initiator.setTimeoutMillis(HL7Constants.DEFAULT_TIMEOUT); } returnMsg = initiator.sendAndReceive(message); connectionHub.detach(connection); if (log.isDebugEnabled()) { log.debug("HL7 message successfully dispatched to URL " + targetEPR); log.debug("Response message received from target EP : " + returnMsg.toString()); } } catch (Exception e) { handleException("Error while sending an HL7 message", e); } if (returnMsg != null) { processResponse(returnMsg, messageContext); } else { handleException("A response not received from the target HL7 endpoint"); } } /** * Send application ack message from the incoming response to the client * @param messageContext * @param outTransportInfo * @throws AxisFault */ private void sendApplicationACKResponse(MessageContext messageContext, OutTransportInfo outTransportInfo) throws AxisFault { HL7ProcessingContext processingContext = ((HL7TransportOutInfo)outTransportInfo).getProcessingContext(); try { Message message = xmlPayloadToHL7Message(messageContext); processingContext.offerApplicationResponses(message,messageContext); } catch (HL7Exception e) { handleException("Error while sending an custom ack message", e); } } /** * Get the response from the messagecontext * @param ctx * @return * @throws HL7Exception */ private Message xmlPayloadToHL7Message(MessageContext ctx) throws HL7Exception { OMElement hl7MsgEl = (OMElement) ctx.getEnvelope().getBody().getChildrenWithName(new QName(HL7Constants.HL7_NAMESPACE, HL7Constants.HL7_MESSAGE_ELEMENT_NAME)) .next(); String hl7XMLPayload = hl7MsgEl.getFirstElement().toString(); return this.xmlparser.parse(hl7XMLPayload); } }