/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * Licensed 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 *******************************************************************************/ package org.ebayopensource.turmeric.runtime.sif.impl.protocolprocessor.soap; import javax.xml.stream.XMLStreamException; import org.apache.axiom.soap.SOAP11Constants; import org.apache.axiom.soap.SOAP12Constants; import org.apache.axiom.soap.SOAPEnvelope; import org.apache.axiom.soap.SOAPFault; import org.apache.axiom.soap.SOAPFaultCode; import org.apache.axiom.soap.SOAPFaultReason; import org.apache.axiom.soap.SOAPFaultRole; import org.apache.axis2.AxisFault; import org.apache.axis2.engine.AxisEngine; import org.ebayopensource.turmeric.runtime.binding.utils.XMLStreamReaderUtils; import org.ebayopensource.turmeric.runtime.common.exceptions.ErrorDataFactory; import org.ebayopensource.turmeric.runtime.common.exceptions.ServiceException; import org.ebayopensource.turmeric.runtime.common.impl.protocolprocessor.soap.Axis2Utils; import org.ebayopensource.turmeric.runtime.common.impl.protocolprocessor.soap.BaseSOAPProtocolProcessor; import org.ebayopensource.turmeric.runtime.common.impl.protocolprocessor.soap.SOAP11Fault; import org.ebayopensource.turmeric.runtime.common.impl.protocolprocessor.soap.SOAP12Fault; import org.ebayopensource.turmeric.runtime.common.impl.protocolprocessor.soap.SOAPUtils; import org.ebayopensource.turmeric.runtime.common.pipeline.InboundMessage; import org.ebayopensource.turmeric.runtime.common.pipeline.MessageContext; import org.ebayopensource.turmeric.runtime.common.types.SOAConstants; import org.ebayopensource.turmeric.runtime.common.types.SOAHeaders; import org.ebayopensource.turmeric.runtime.errorlibrary.ErrorConstants; /** * Title: ClientSOAPProtocolProcessor.java * Description: * Copyright: Copyright (c) 2007 * Company: eBay * @author Gary Yue * @version 1.0 * * Axis2 Protocol Processor implementation for client */ public class ClientSOAPProtocolProcessor extends BaseSOAPProtocolProcessor { public void beforeRequestPipeline(MessageContext ctx) throws ServiceException { // NOOP } /** * For client: Execute Axis2 outbound pipeline here */ public void beforeRequestDispatch(MessageContext ctx) throws ServiceException { //System.out.println("ClientSOAPProtocolProcessor: beforeRequestDispatch -- calling Axis Outbound pipeline!"); org.apache.axis2.context.MessageContext axis2OutContext; try { // create Axis outbound context axis2OutContext = Axis2Utils.createOutboundAxis2Context(ctx, m_configContext); // create SOAP envelope SOAPEnvelope env = null; if (getMessageProtocol().equals(SOAConstants.MSG_PROTOCOL_SOAP_12)) { env = SOAPUtils.createSOAP12Envelope(null); } else if (getMessageProtocol().equals(SOAConstants.MSG_PROTOCOL_SOAP_11)) { env = SOAPUtils.createSOAP11Envelope(null); } else { throw new ServiceException(ErrorDataFactory.createErrorData(ErrorConstants.SVC_PROTOCOLPROCESSOR_OUTBOUND_SYSTEM_ERROR, ErrorConstants.ERRORDOMAIN, new Object[]{getMessageProtocol(), "ERROR: Unknown message protocol name specified"})); } // after setting envelope to context, context will now know whether this is SOAP11 or SOAP12 axis2OutContext.setEnvelope(env); // overwrite the content-type here if it's not SOAP1.1 (which means it's SOAP1.2) if (!axis2OutContext.isSOAP11()) { setSOAP12ContentType( ctx.getRequestMessage()); } // send via axis2 outbound pipeline AxisEngine.send(axis2OutContext); // add AxisOutContext to our message context, to be accessed on the client inbound flow ctx.setProperty(AXIS_OUT_CONTEXT, axis2OutContext); } catch (AxisFault e) { throw new ServiceException(ErrorDataFactory.createErrorData(ErrorConstants.SVC_PROTOCOLPROCESSOR_OUTBOUND_SYSTEM_ERROR, ErrorConstants.ERRORDOMAIN, new Object[]{getMessageProtocol(), e.getMessage()}), e); } catch (Exception e) { throw new ServiceException(ErrorDataFactory.createErrorData(ErrorConstants.SVC_PROTOCOLPROCESSOR_OUTBOUND_SYSTEM_ERROR, ErrorConstants.ERRORDOMAIN, new Object[]{getMessageProtocol(), e.getMessage()}), e); } } /** * For client: Execute Axis2 inbound pipeline here */ public void beforeResponsePipeline(MessageContext ctx) throws ServiceException { //System.out.println("ClientSOAPProtocolProcessor: beforeResponsePipeline -- calling Axis Inbound pipeline!"); // error checking: if already contain error, just return if (ctx.hasErrors()) { return; } org.apache.axis2.context.MessageContext axis2OutContext = (org.apache.axis2.context.MessageContext) ctx.getProperty(AXIS_OUT_CONTEXT); if (axis2OutContext == null ) { throw new ServiceException(ErrorDataFactory.createErrorData(ErrorConstants.SVC_PROTOCOLPROCESSOR_INBOUND_SYSTEM_ERROR, ErrorConstants.ERRORDOMAIN, new Object[] {getMessageProtocol(), "Outbound axis2 context not found from message context"})); } org.apache.axis2.context.MessageContext axis2InContext = null; InboundMessage respMsg = (InboundMessage) ctx.getResponseMessage(); try { // create Axis Inbound context from outbound axis2InContext = Axis2Utils.createInboundAxis2ContextFromOutbound(axis2OutContext); ctx.setProperty(AXIS_IN_CONTEXT, axis2InContext); SOAPEnvelope resEnvelope = null; // create response envelope if (axis2InContext.getEnvelope() == null) { resEnvelope = SOAPUtils.createSOAPEnvelope(respMsg.getXMLStreamReader(), axis2OutContext.getEnvelope().getNamespace().getNamespaceURI()); if (resEnvelope != null) { axis2InContext.setEnvelope(resEnvelope); } else { throw new ServiceException(ErrorDataFactory.createErrorData(ErrorConstants.SVC_PROTOCOLPROCESSOR_INBOUND_SYSTEM_ERROR, ErrorConstants.ERRORDOMAIN, new Object[]{getMessageProtocol(), "Error creating envelope for inbound message!"})); } } // this is called to trigger the deserialization of the headers, and stored them in memory, prior to axis deserialization try { respMsg.getMessageHeadersAsJavaObject(); respMsg.getMessageBody(); } catch(Exception e) { // consume all exception here. throw new ServiceException(ErrorDataFactory.createErrorData(ErrorConstants.SVC_PROTOCOLPROCESSOR_INBOUND_SYSTEM_ERROR, ErrorConstants.ERRORDOMAIN, new Object[]{getMessageProtocol(), "Payload Body or Header could not be parsed."}), e); } if (resEnvelope != null) { // pass to axis engine AxisEngine.receive(axis2InContext); // advance to the next start element //XMLStreamReaderUtils.advanceToNextStartElement(respMsg.getXMLStreamReader()); // error flow case if (respMsg.getXMLStreamReader().getName().getLocalPart().equals(SOAP_FAULT_NAME)) { respMsg.setTransportHeader(SOAHeaders.ERROR_RESPONSE, "true"); // SOA 2.1 Addition if (axis2InContext.isFault()) { SOAPFault soapFault = axis2InContext.getEnvelope().getBody().getFault(); SOAPFaultCode faultCode = soapFault.getCode(); SOAPFaultReason faultReason = soapFault.getReason(); SOAPFaultRole faultRole = null; // This element is optional, so we need to make sure we don't step too far String curNodeName = respMsg.getXMLStreamReader().getName().getLocalPart(); if (SOAP_FAULT_ACTOR_NAME.equalsIgnoreCase(curNodeName) || SOAP_FAULT_ROLE_NAME.equalsIgnoreCase(curNodeName)) { faultRole = soapFault.getRole(); } String faultCodeStr = (faultCode != null) ? faultCode.getText() : null; String faultReasonStr = (faultReason != null) ? faultReason.getText() : null; String faultRoleStr = (faultRole != null) ? faultRole.getText() : null; if (axis2InContext.isSOAP11()) { SOAP11Fault soap11Fault = new SOAP11Fault(faultCodeStr, faultReasonStr, faultRoleStr); ctx.setProperty(BaseSOAPProtocolProcessor.SOAP_FAULT_OBJECT, soap11Fault); } else { SOAP12Fault soap12Fault = new SOAP12Fault(faultCodeStr, faultReasonStr, faultRoleStr); ctx.setProperty(BaseSOAPProtocolProcessor.SOAP_FAULT_OBJECT, soap12Fault); } } String faultTag = (SOAPUtils.isSOAP12Envelope(resEnvelope) ? SOAP12Constants.SOAP_FAULT_DETAIL_LOCAL_NAME : SOAP11Constants.SOAP_FAULT_DETAIL_LOCAL_NAME); // In the case of fault, need to consume advance the XML Reader to the start of the fault detail element (ErrorMessage object) if (!(XMLStreamReaderUtils.advanceToAfterStartElement(respMsg.getXMLStreamReader(), faultTag))) { throw new ServiceException(ErrorDataFactory.createErrorData(ErrorConstants.SVC_PROTOCOLPROCESSOR_DATA_DESERIALIZATION_ERROR, ErrorConstants.ERRORDOMAIN, new Object[]{getMessageProtocol(), "Failed to advance XMLReader to fault <" + faultTag + "> tag!"})); } } } } catch(XMLStreamException e) { throw new ServiceException(ErrorDataFactory.createErrorData(ErrorConstants.SVC_PROTOCOLPROCESSOR_DATA_READ_ERROR, ErrorConstants.ERRORDOMAIN, new Object[]{getMessageProtocol(), e.getMessage()}), e); } catch(ServiceException e) { throw e; } catch(Exception e) { throw new ServiceException(ErrorDataFactory.createErrorData(ErrorConstants.SVC_PROTOCOLPROCESSOR_INBOUND_SYSTEM_ERROR, ErrorConstants.ERRORDOMAIN, new Object[]{getMessageProtocol(), e.getMessage()}), e); } } /** * Execute Axis2 outbound pipeline here */ public void beforeResponseDispatch(MessageContext ctx) throws ServiceException { // NOOP } }