Package org.apache.muse.ws.addressing.soap

Source Code of org.apache.muse.ws.addressing.soap.SimpleSoapClient

/*=============================================================================*
*  Copyright 2006 The Apache Software Foundation
*
*  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
*
*  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.apache.muse.ws.addressing.soap;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.apache.muse.util.messages.Messages;
import org.apache.muse.util.messages.MessagesFactory;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.ws.addressing.EndpointReference;
import org.apache.muse.ws.addressing.MessageHeaders;
import org.apache.muse.ws.addressing.soap.SoapClient;

/**
*
* SimpleSoapClient is and implementation of {@linkplain SoapClient SoapClient}
* that relies on the java.net.HttpURLConnection API to send and receive
* SOAP messages. It provides complete WS-Addressing (WS-A) support, so that
* all requests are routed with WS-A EPRs and Actions. Messages are sent with
* valid reply and fault EPRs so that responses can be redirected if desired.
*
* @author Dan Jemiolo (danj)
*
*/

public class SimpleSoapClient implements SoapClient
{
    //
    // Used to lookup all exception messages
    //
    private static Messages _MESSAGES =
        MessagesFactory.get(SimpleSoapClient.class);
   
    private static final Element[] _EMPTY_BODY = new Element[0];
   
    //
    // Set to 0...65535 if TCP/SOAP monitor is in use
    //
    private int _monitorPort = -1;
   
    //
    // Print all SOAP messages if true - default is false.
    //
    private boolean _trace = false;
   
    //
    // The stream used for tracing - the default is stdout
    //
    private PrintWriter _traceWriter = new PrintWriter(System.out);
   
    /**
     *
     * Creates a valid SOAP message, including WS-A headers that specify
     * the destination and operation (action). The WS-A headers include
     * proper return/fault information for the recipient to use in response.
     *
     * @param source
     * @param destination
     * @param action
     * @param bodyElements
     *
     * @return A valid SOAP message that can be sent to the destination.
     *
     */
    protected Element createMessage(EndpointReference source,
                                    EndpointReference destination,
                                    String action,
                                    Element[] bodyElements)
    {
        Document doc = XmlUtils.createDocument();
        Element soapXML = XmlUtils.createElement(doc, SoapConstants.ENVELOPE_QNAME);
       
        //
        // add WS-Addressing headers
        //
        MessageHeaders headers = new MessageHeaders(destination, action);
       
        //
        // if there's a source EPR, we can provide a wsa:From
        //
        if (source != null)
            headers.setFromAddress(source);

        Element headersXML = headers.toXML(doc);
        soapXML.appendChild(headersXML);
       
        //
        // copy data into SOAP body
        //
        Element bodyXML = XmlUtils.createElement(doc, SoapConstants.BODY_QNAME);
        soapXML.appendChild(bodyXML);
       
        for (int n = 0; n < bodyElements.length; ++n)
        {
            if (bodyElements[n].getOwnerDocument() != doc)
                bodyElements[n] = (Element)doc.importNode(bodyElements[n], true);
           
            bodyXML.appendChild(bodyElements[n]);
        }
       
        return soapXML;
    }
   
    /**
     *
     * @param destination
     *
     * @return The URL of the EPR's wsa:Address. If SOAP monitoring is on,
     *         the URL's port is switched to the monitor port.
     *
     */
    protected URL getDestinationURL(EndpointReference destination)
    {
        URI uri = destination.getAddress();
       
        //
        // for TCP/SOAP monitoring, copy the URI with the new port.
        // we have to make a new object because URI's are immutable.
        //
        try
        {
            if (isUsingSoapMonitor())
                uri = new URI(uri.getScheme(),
                              uri.getUserInfo(),
                              uri.getHost(),
                              getSoapMonitorPort(),
                              uri.getPath(),
                              uri.getQuery(),
                              uri.getFragment());
           
            return uri.toURL();
        }
       
        catch (Throwable error)
        {
            throw new RuntimeException(error.getMessage(), error);
        }
    }
   
    public int getSoapMonitorPort()
    {
        return _monitorPort;
    }
   
    public PrintWriter getTraceWriter()
    {
        return _traceWriter;
    }
   
    /**
     *
     * {@inheritDoc}
     * <br><br>
     * The default value is 'false'.
     *
     */   
    public boolean isUsingSoapMonitor()
    {
        return _monitorPort >= 0;
    }
   
    /**
     *
     * {@inheritDoc}
     * <br><br>
     * The default value is 'false'.
     *
     */
    public boolean isUsingTrace()
    {
        return _trace;
    }
   
    public Element[] send(EndpointReference src,
                          EndpointReference dest,
                          String wsaAction,
                          Element[] body)
    {
        if (dest == null)
            throw new NullPointerException(_MESSAGES.get("NullDestinationEPR"));

        if (wsaAction == null)
            throw new NullPointerException(_MESSAGES.get("NullActionURI"));

        if (body == null)
            body = _EMPTY_BODY;
       
        //
        // create the request message and turn it into bytes
        //
        Element soapRequest = createMessage(src, dest, wsaAction, body);
        byte[] soapBytes = XmlUtils.toString(soapRequest).getBytes();
       
        if (isUsingTrace())
            trace(soapRequest, false);
       
        Element soapResponse = null;
       
        try
        {
            //
            // set up the HTTP request - POST of SOAP 1.2 data
            //
            URL url = getDestinationURL(dest);
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-type", SoapConstants.CONTENT_TYPE_HEADER);
            connection.setDoOutput(true);
            connection.connect();
           
            //
            // send the SOAP request...
            //
            OutputStream output = connection.getOutputStream();
            output.write(soapBytes);
            output.flush();
            output.close();
           
            //
            // read in the response and build an XML document from it
            //
            InputStream input = connection.getInputStream();
           
            Document responseDoc = XmlUtils.createDocument(input);
            soapResponse = XmlUtils.getFirstElement(responseDoc);
           
            input.close();
            connection.disconnect();
        }
       
        catch (Throwable error)
        {
            SoapFault soapFault = new SoapFault(error);
            return new Element[]{ soapFault.toXML() };
        }
       
        if (isUsingTrace())
            trace(soapResponse, true);
       
        //
        // return the elements inside the SOAP body
        //
        Element responseBody = XmlUtils.getElement(soapResponse, SoapConstants.BODY_QNAME);
        return XmlUtils.getAllElements(responseBody);
    }
   
    public void setTrace(boolean trace)
    {
        _trace = trace;
    }
   
    /**
     *
     * {@inheritDoc}
     * <br><br>
     * Note that there is a default PrintWriter set at instantiation - it
     * wraps the System.out stream.
     *
     */
    public void setTraceWriter(PrintWriter writer)
    {
        if (writer == null)
            throw new NullPointerException(_MESSAGES.get("NullTraceWriter"));
       
        _traceWriter = writer;
    }
   
    public void startSoapMonitor(int monitorPort)
    {
        if (monitorPort < 1)
        {
            Object[] filler = { new Integer(monitorPort) };
            throw new RuntimeException(_MESSAGES.get("InvalidPort", filler));
        }
       
        _monitorPort = monitorPort;
    }
   
    public void stopSoapMonitor()
    {
        _monitorPort = -1;
    }
   
    /**
     *
     * @param xml
     *        An XML fragment that will be sent to the trace log.
     *
     * @param incoming
     *        True if the message was part of an incoming SOAP message. This
     *        merely provides some context in the trace log.
     *
     */
    protected void trace(Element xml, boolean incoming)
    {
        PrintWriter writer = getTraceWriter();
        writer.write("[CLIENT TRACE] SOAP envelope contents (");
        writer.write(incoming ? "incoming" : "outgoing");
        writer.write("):\n\n");
        writer.write(XmlUtils.toString(xml, false));
        writer.write('\n');
        writer.flush();
    }
   
    /**
     *
     * @param message
     *        The message to print to the trace log.
     *
     */
    protected void trace(String message)
    {
        PrintWriter writer = getTraceWriter();
        writer.write("[CLIENT TRACE] ");
        writer.write(message);
        writer.write('\n');
        writer.flush();
    }
}
TOP

Related Classes of org.apache.muse.ws.addressing.soap.SimpleSoapClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.