package gov.nist.registry.common2.soap; import gov.nist.registry.common2.exception.ExceptionUtil; import gov.nist.registry.common2.exception.XdsException; import gov.nist.registry.common2.exception.XdsFormatException; import gov.nist.registry.common2.exception.XdsInternalException; import gov.nist.registry.common2.registry.MetadataSupport; import gov.nist.registry.common2.xml.Util; import gov.nist.registry.ws.serviceclasses.XdsService; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.apache.axiom.om.OMElement; import org.apache.axiom.soap.SOAP11Constants; import org.apache.axiom.soap.SOAP12Constants; import org.apache.axis2.AxisFault; import org.apache.axis2.Constants; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.context.MessageContext; import org.apache.axis2.context.OperationContext; import org.apache.axis2.transport.http.HTTPConstants; import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.logging.LogFactory; public class Soap implements SoapInterface { private final static org.apache.commons.logging.Log logger = LogFactory.getLog(Soap.class); ServiceClient serviceClient = null; OMElement result = null; boolean async; String expectedReturnAction; boolean mtom; boolean addressing; boolean soap12; List<OMElement> additionalHeaders = null; public Soap() { async = false; expectedReturnAction = null; mtom = false; addressing = true; soap12 = true; } public void addHeader(OMElement header) { if (additionalHeaders == null) additionalHeaders = new ArrayList<OMElement>(); additionalHeaders.add(header); } public void clearHeaders() { additionalHeaders = null; } public void setAsync(boolean async) { this.async = async; } public void soapSend(OMElement body, Protocol protocol, String endpoint, boolean mtom, boolean addressing, boolean soap12, String action) throws XdsException, AxisFault { this.expectedReturnAction = null; this.mtom = mtom; this.addressing = addressing; this.soap12 = soap12; soapSend(body, protocol, endpoint, action); } public OMElement soapCall(OMElement body, Protocol protocol, String endpoint, boolean mtom, boolean addressing, boolean soap12, String action, String expected_return_action) throws XdsException, AxisFault { this.expectedReturnAction = expected_return_action; this.mtom = mtom; this.addressing = addressing; this.soap12 = soap12; return soapCall(body, protocol, endpoint, action); } public void soapSend(OMElement body, Protocol protocol, String endpoint, String action) throws XdsException, AxisFault { // if (1 == 1) { // soapCall(body, endpoint, action); // return; // } // try { if (serviceClient == null) serviceClient = new ServiceClient(); serviceClient.getOptions().setTo(new EndpointReference(endpoint)); try { serviceClient.getOptions().setFrom(new EndpointReference(InetAddress.getLocalHost().getHostAddress())); } catch (UnknownHostException e) { throw new XdsException(ExceptionUtil.exception_details(e)); } if (System.getenv("XDSHTTP10") != null) { logger.info("Generating HTTP 1.0"); serviceClient.getOptions().setProperty (org.apache.axis2.transport.http.HTTPConstants.HTTP_PROTOCOL_VERSION, org.apache.axis2.transport.http.HTTPConstants.HEADER_PROTOCOL_10); serviceClient.getOptions().setProperty (org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE); } serviceClient.getOptions().setProperty(Constants.Configuration.ENABLE_MTOM, ((mtom) ? Constants.VALUE_TRUE : Constants.VALUE_FALSE)); serviceClient.getOptions().setAction(action); if (addressing) { serviceClient.engageModule("addressing"); } else { serviceClient.disengageModule("addressing"); // this does not work in Axis2 yet } serviceClient.getOptions().setSoapVersionURI( ((soap12) ? SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI : SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI) ); // System.out.println("fire and forget " + endpoint); // serviceClient.fireAndForget(body); logger.info("sendRobust " + endpoint); serviceClient.sendRobust(body); } public OMElement soapCall(OMElement body, Protocol protocol, String endpoint, String action) throws XdsException, AxisFault { // try { if (serviceClient == null) serviceClient = new ServiceClient(); serviceClient.getOptions().setTo(new EndpointReference(endpoint)); if (System.getenv("XDSHTTP10") != null) { logger.info("Generating HTTP 1.0"); serviceClient.getOptions().setProperty (org.apache.axis2.transport.http.HTTPConstants.HTTP_PROTOCOL_VERSION, org.apache.axis2.transport.http.HTTPConstants.HEADER_PROTOCOL_10); serviceClient.getOptions().setProperty (org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE); } serviceClient.getOptions().setProperty(Constants.Configuration.ENABLE_MTOM, ((mtom) ? Constants.VALUE_TRUE : Constants.VALUE_FALSE)); serviceClient.getOptions().setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER, protocol); serviceClient.getOptions().setAction(action); if (addressing) { serviceClient.engageModule("addressing"); } else { serviceClient.disengageModule("addressing"); // this does not work in Axis2 yet } if (additionalHeaders != null) { for (OMElement hdr : additionalHeaders) { serviceClient.addHeader(hdr); } } serviceClient.getOptions().setSoapVersionURI( ((soap12) ? SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI : SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI) ); if ( async && !serviceClient.getOptions().isUseSeparateListener()) serviceClient.getOptions().setUseSeparateListener(async); if (logger.isInfoEnabled()) { logger.info("Call " + endpoint); logger.info("Action " + action); } OMElement result = serviceClient.sendReceive(body); if (async) serviceClient.cleanupTransport(); Object in = serviceClient.getServiceContext().getLastOperationContext().getMessageContexts().get("In"); if ( ! (in instanceof MessageContext)) throw new XdsInternalException("Soap: In MessageContext of type " + in.getClass().getName() + " instead of MessageContext"); MessageContext inMsgCxt = (MessageContext) in; boolean responseMtom = inMsgCxt.isDoingMTOM(); if ( mtom != responseMtom) if (mtom) { throw new XdsFormatException("Request was MTOM format but response was SIMPLE SOAP"); } else { throw new XdsFormatException("Request was SIMPLE SOAP but response was MTOM"); } this.result = result; if (async) verify_returned_action(expectedReturnAction, "urn:mediateResponse"); else verify_returned_action(expectedReturnAction, null); return result; // } catch (AxisFault e) { // throw new XdsException(ExceptionUtil.exception_details(e)); // } } public OMElement getResult() { return result; } void verify_returned_action(String expected_return_action, String alternate_return_action) throws XdsException { if (expected_return_action == null) return; OMElement hdr = getInHeader(); if (hdr == null && expected_return_action != null) throw new XdsInternalException("No SOAPHeader returned: expected header with action = " + expected_return_action); OMElement action = MetadataSupport.firstChildWithLocalName(hdr, "Action"); if (action == null && expected_return_action != null) throw new XdsInternalException("No action returned in SOAPHeader: expected action = " + expected_return_action); String action_value = action.getText(); if (alternate_return_action == null) { if ( action_value == null || !action_value.equals(expected_return_action)) throw new XdsInternalException("Wrong action returned in SOAPHeader: expected action = " + expected_return_action + " returned action = " + action_value); } else { if ( action_value == null || ( (!action_value.equals(expected_return_action)) && (!action_value.equals(alternate_return_action)) ) ) throw new XdsInternalException("Wrong action returned in SOAPHeader: expected action = " + expected_return_action + " returned action = " + action_value); } } public OMElement getInHeader() throws XdsInternalException { OperationContext oc = serviceClient.getLastOperationContext(); HashMap<String, MessageContext> ocs = oc.getMessageContexts(); MessageContext in = ocs.get("In"); if (in == null) return null; if (in.getEnvelope() == null) return null; if (in.getEnvelope().getHeader() == null) return null; return Util.deep_copy( in.getEnvelope().getHeader()); } public OMElement getOutHeader() throws XdsInternalException { OperationContext oc = serviceClient.getLastOperationContext(); HashMap<String, MessageContext> ocs = oc.getMessageContexts(); MessageContext out = ocs.get("Out"); if (out == null) return null; return Util.deep_copy( out.getEnvelope().getHeader()); } public String getExpectedReturnAction() { return expectedReturnAction; } public void setExpectedReturnAction(String expectedReturnAction) { this.expectedReturnAction = expectedReturnAction; } public boolean isMtom() { return mtom; } public void setMtom(boolean mtom) { this.mtom = mtom; } public boolean isAddressing() { return addressing; } public void setAddressing(boolean addressing) { this.addressing = addressing; } public boolean isSoap12() { return soap12; } public void setSoap12(boolean soap12) { this.soap12 = soap12; } public boolean isAsync() { return async; } }