Package org.jboss.soa.esb.actions.soap

Source Code of org.jboss.soa.esb.actions.soap.AbstractWsdlContractPublisher

/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and others contributors as indicated
* by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* (C) 2005-2008, JBoss Inc.
*/
package org.jboss.soa.esb.actions.soap;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URI;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.log4j.Logger;
import org.jboss.internal.soa.esb.publish.ActionContractPublisher;
import org.jboss.internal.soa.esb.publish.ContractInfo;
import org.jboss.internal.soa.esb.publish.ServletContractPublisher;
import org.jboss.internal.soa.esb.util.StreamUtils;
import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.Service;
import org.jboss.soa.esb.addressing.EPR;
import org.jboss.soa.esb.http.HttpClientFactory;
import org.jboss.soa.esb.lifecycle.LifecycleResourceException;
import org.jboss.soa.esb.listeners.config.Action;
import org.jboss.soa.esb.smooks.resource.SmooksResource;
import org.milyn.Smooks;
import org.milyn.container.ExecutionContext;
import org.xml.sax.SAXException;

/**
* Abstract WSDL contract publisher.
*
* @author <a href="mailto:tom.fennelly@jboss.com">tom.fennelly@jboss.com</a>
*/
public abstract class AbstractWsdlContractPublisher implements ActionContractPublisher, ServletContractPublisher {
  
    private static Logger logger = Logger.getLogger(AbstractWsdlContractPublisher.class);

    public static final String REWRITE_ENDPOINT_URL = "rewrite-endpoint-url";

    private Properties actionProperties;
    private boolean rewriteEndpointUrl = true;
    private Smooks transformer;

    /**
     * Set the {@link SOAPProcessor} action configuration.
     * @param actionConfig action config.
     * @throws ConfigurationException Bad config.
     */
    public void setActionConfig(Action actionConfig) throws ConfigurationException {
        actionProperties = actionConfig.getProperties();

        final String rewriteEndpointUrlVal = actionProperties.getProperty(AbstractWsdlContractPublisher.REWRITE_ENDPOINT_URL);
        if (rewriteEndpointUrlVal != null) {
            rewriteEndpointUrl = !rewriteEndpointUrlVal.equals("false");
        }

        initializeTransformer();
    }

    /**
     * Get the action properties.
     * @return The action properties.
     */
    public Properties getActionProperties() {
        return actionProperties;
    }
   
    /**
     * Set the action properties.
     */
    protected void setActionProperties(Properties actionProperties) {
      this.actionProperties = actionProperties;
    }

    /**
     * Get the WSDL Address.
     * @return The WSDL address.
     */
    public abstract String getWsdlAddress();

    /**
     * Get the {@link org.jboss.soa.esb.http.HttpClientFactory} properties.
     * <p/>
     * We use HttpClient (configurable via the {@link org.jboss.soa.esb.http.HttpClientFactory})
     * to load the WSDL.  This way, we can support different auth mechanisms etc.
     *
     * @return The {@link org.jboss.soa.esb.http.HttpClientFactory} properties.
     */
    public abstract Properties getHttpClientProperties();

    /**
     * Get the contract configuration.
     * <p/>
     * This method impl basically returns the Endpoint WSDL, modified for
     * the supplied EPR and its channel.
     *
     * @param epr Endpoint EPR.
     * @return WSDL Contract.
     */
    public ContractInfo getContractInfo(EPR epr) {
        HttpServletRequest httpServletRequestProxy;

        httpServletRequestProxy = (HttpServletRequest) Proxy.newProxyInstance(HttpServletRequest.class.getClassLoader(),
                                          new Class[] { HttpServletRequest.class },
                                          new HttpServletRequestHandler());

        return getContractInfo(epr, httpServletRequestProxy);
    }

    public ContractInfo getContractInfo(EPR epr, HttpServletRequest servletRequest) {
        String wsdlAddress = getWsdlAddress();
        if (wsdlAddress != null) {
            String targetServiceCat = servletRequest.getParameter("serviceCat");
            String targetServiceName = servletRequest.getParameter("serviceName");
            String targetProtocol = servletRequest.getParameter("protocol");
            ContractInfo contract;
            try {
                // Generate the WSDL...
                contract = getContractInfo(Service.getService(targetServiceCat, targetServiceName), wsdlAddress);
                String data = contract.getData();
                if (data != null) {
                  contract.setData( updateWsdl(data, epr, targetServiceCat, targetServiceName, targetProtocol) );
                } else {
                  throw new Exception("null Contract data");
                }
            } catch (Exception e) {
              String e_msg = "Failed to load WSDL contract information from address '" + wsdlAddress + "': " + e.getMessage();
              logger.error(e_msg, e);
              contract = new ContractInfo("text/xml", "<definitions><!-- " + e_msg + " --></definitions>");
            }
            return contract;
        } else {
            logger.warn("Requested contract info for unknown webservice endpoint.");
            return null;
        }
    }
   
    public ContractInfo getContractInfo(Service service, String wsdlAddress) throws IOException {
      return new ContractInfo( "text/xml", getWsdl(wsdlAddress) );
    }

    /**
     * Get the WSDL.
     * @param wsdlAddress The WSDL address.
     * @return The WSDL.
     * @throws IOException Error reading wsdl.
     */
    public String getWsdl(String wsdlAddress) throws IOException {
      return this.getWsdl(wsdlAddress, null);
    }
   
    /**
     * Get the WSDL.
     * @param wsdlAddress The WSDL address.
     * @param charsetNameOverride The charset name override.
     * @return The WSDL.
     * @throws IOException Error reading wsdl.
     */
    public String getWsdl(String wsdlAddress, String charsetNameOverride) throws IOException {
        RemoteWsdlLoader loader;

        try {
            Properties httpClientProperties = getHttpClientProperties();

            httpClientProperties = (Properties) httpClientProperties.clone();
            if(!httpClientProperties.containsKey(HttpClientFactory.TARGET_HOST_URL)) {
                httpClientProperties.setProperty(HttpClientFactory.TARGET_HOST_URL, wsdlAddress);
            }

            loader = new RemoteWsdlLoader(httpClientProperties);
        } catch (ConfigurationException e) {
            throw (IOException)(new IOException("Failed to create RemoteWsdlLoader instance.").initCause(e));
        }

        try {
            InputStream wsdlStream = loader.load(wsdlAddress, charsetNameOverride);
            try {
                return StreamUtils.readStreamString(wsdlStream, "UTF-8");
            } finally {
                wsdlStream.close();
            }
        } finally {
            loader.shutdown();
        }
    }

    /**
     * Update the supplied wsdl to take account of the ESB endpoint proxying of the JBossWS
     * invocation, as well as the fact that the transport may be different.
     *
     * @param wsdl WSDL input.
     * @param epr The SOAP endpoint from the ESB perspective.
     * @param targetServiceCat
     * @param targetServiceName
     * @param targetProtocol @return The updated WSDL.
     */
    protected String updateWsdl(String wsdl, EPR epr, String targetServiceCat, String targetServiceName, String targetProtocol) throws SAXException, IOException, ConfigurationException {
        wsdl = applyTransformer(wsdl, epr, targetServiceCat, targetServiceName, targetProtocol);

        return wsdl.trim();
    }

    /**
     * Initialize the endpoint rewriting transformer.
     * @throws ConfigurationException Failed to initialize transformer.
     */
    protected void initializeTransformer() throws ConfigurationException {
        try {
            // Initialise the transformer with the rewriting resource configs...
            transformer = SmooksResource.createSmooksResource("/org/jboss/soa/esb/actions/soap/wsdltrans.xml");

            // And add the user defined config, if there is one....
            String wsdlTransformConfig = actionProperties.getProperty("wsdlTransform");
            if(wsdlTransformConfig != null) {
                try {
                    transformer.addConfigurations(wsdlTransformConfig);
                } catch (IOException e) {
                    throw new ConfigurationException("Failed to read the User Defined WSDL Transformation config '" + wsdlTransformConfig + "'.", e);
                } catch (SAXException e) {
                    throw new ConfigurationException("Failed to read the User Defined WSDL Transformation config '" + wsdlTransformConfig + "'.", e);
                }
            }
        } catch (final LifecycleResourceException lre) {
            throw new ConfigurationException("Failed to read the Endpoint Transformation config for WSDL.", lre);
        } catch (IOException e) {
            throw new ConfigurationException("Failed to read the Endpoint Transformation config for WSDL.", e);
        } catch (SAXException e) {
            throw new ConfigurationException("Failed to read the Endpoint Transformation config for WSDL.", e);
        }
    }

    /**
     * Perform the endpoint rewrite.
     * @param wsdl The WSDL to be transformed.
     * @param epr The target endpoint EPR on the ESB.
     * @param targetServiceCat The Service Category.
     * @param targetServiceName The Service Name.
     * @param targetProtocol The target protocol.
     * @return The rewritten WSDL.
     */
    private String applyTransformer(String wsdl, EPR epr, String targetServiceCat, String targetServiceName, String targetProtocol) {
        URI endpointURI = URI.create(epr.getAddr().getAddress());
        StringWriter writer = new StringWriter();
        ExecutionContext execContext = transformer.createExecutionContext();

        execContext.setAttribute(WsdlEndpointTransformer.REWRITE_ENDPOINT_URL, rewriteEndpointUrl);
        execContext.setAttribute(WsdlEndpointTransformer.ENDPOINT_URI, endpointURI);
        execContext.setAttribute(WsdlEndpointTransformer.TARGET_CAT, (targetServiceCat != null?targetServiceCat:""));
        execContext.setAttribute(WsdlEndpointTransformer.TARGET_NAME, (targetServiceName != null?targetServiceName:""));
        execContext.setAttribute(WsdlEndpointTransformer.TARGET_PROTOCOL, (targetProtocol != null?targetProtocol:""));
        transformer.filterSource(execContext, new StreamSource(new StringReader(wsdl)), new StreamResult(writer));

        return writer.toString().trim();
    }

    private static class HttpServletRequestHandler implements InvocationHandler {

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if(method.getName().equals("getRequestURL")) {
                return new StringBuffer("http://www.jboss.org");
            }

            return null;
        }
    }
}
TOP

Related Classes of org.jboss.soa.esb.actions.soap.AbstractWsdlContractPublisher

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.