EsbWebServiceDeployer.java :  » JBoss » jbossesb-4.7 » org » jboss » soa » esb » listeners » deployers » mc » Java Open Source

Java Open Source » JBoss » jbossesb 4.7 
jbossesb 4.7 » org » jboss » soa » esb » listeners » deployers » mc » EsbWebServiceDeployer.java
/*
 * JBoss, Home of Professional Open Source Copyright 2009, Red Hat Middleware
 * LLC, and individual contributors by the @authors tag. See the copyright.txt
 * in the distribution for a full listing of individual contributors.
 * 
 * This is free software; you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 * 
 * This software is distributed in the hope that it will be useful, but WITHOUT
 * ANY 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
 * along with this software; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
 * site: http://www.fsf.org.
 */
package org.jboss.soa.esb.listeners.deployers.mc;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.log4j.Logger;
import org.jboss.deployers.spi.DeploymentException;
import org.jboss.deployers.spi.deployer.DeploymentStages;
import org.jboss.deployers.vfs.spi.deployer.AbstractSimpleVFSRealDeployer;
import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit;
import org.jboss.internal.soa.esb.listeners.war.Filter;
import org.jboss.internal.soa.esb.listeners.war.SecurityConstraints;
import org.jboss.internal.soa.esb.listeners.war.Servlet;
import org.jboss.internal.soa.esb.listeners.war.WebModel;
import org.jboss.internal.soa.esb.publish.ContractReferencePublisher;
import org.jboss.internal.soa.esb.publish.DefaultContractReferencePublisher;
import org.jboss.internal.soa.esb.util.JBossDeployerUtil;
import org.jboss.internal.soa.esb.webservice.ESBResponseFilter;
import org.jboss.internal.soa.esb.webservice.ESBServiceContractReferencePublisher;
import org.jboss.internal.soa.esb.webservice.ESBServiceEndpointInfo;
import org.jboss.internal.soa.esb.webservice.JAXWSProviderClassGenerator;
import org.jboss.internal.soa.esb.webservice.WebServicePublishException;
import org.jboss.metadata.common.jboss.WebserviceDescriptionMetaData;
import org.jboss.metadata.common.jboss.WebserviceDescriptionsMetaData;
import org.jboss.metadata.javaee.spec.ParamValueMetaData;
import org.jboss.metadata.javaee.spec.SecurityRoleMetaData;
import org.jboss.metadata.javaee.spec.SecurityRolesMetaData;
import org.jboss.metadata.web.jboss.JBossServletMetaData;
import org.jboss.metadata.web.jboss.JBossServletsMetaData;
import org.jboss.metadata.web.jboss.JBossWebMetaData;
import org.jboss.metadata.web.spec.AuthConstraintMetaData;
import org.jboss.metadata.web.spec.FilterMappingMetaData;
import org.jboss.metadata.web.spec.FilterMetaData;
import org.jboss.metadata.web.spec.FiltersMetaData;
import org.jboss.metadata.web.spec.LoginConfigMetaData;
import org.jboss.metadata.web.spec.SecurityConstraintMetaData;
import org.jboss.metadata.web.spec.ServletMappingMetaData;
import org.jboss.metadata.web.spec.TransportGuaranteeType;
import org.jboss.metadata.web.spec.UserDataConstraintMetaData;
import org.jboss.metadata.web.spec.WebResourceCollectionMetaData;
import org.jboss.metadata.web.spec.WebResourceCollectionsMetaData;
import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.Service;
import org.jboss.soa.esb.helpers.KeyValuePair;
import org.jboss.soa.esb.listeners.config.ModelUtil;
import org.jboss.soa.esb.listeners.config.ServiceContract;
import org.jboss.soa.esb.listeners.config.WebserviceInfo;
import org.jboss.soa.esb.listeners.deployers.mc.util.VfsUtil;
import org.jboss.virtual.MemoryFileFactory;
import org.jboss.virtual.VirtualFile;

/**
 * EsbWebServiceDeployer is responsible for deploying the web service that will
 * expose the underlying ESB service as a web service.
 * <p/>
 * 
 * @author <a href="mailto:dbevenius@jboss.com">Daniel Bevenius</a>
 *
 */
public class EsbWebServiceDeployer extends AbstractSimpleVFSRealDeployer<EsbMetaData>
{
    /** Logger */
    private Logger log = Logger.getLogger(EsbWebServiceDeployer.class);
    
    /**
     * Key used for attaching a VirtualFile representing a ref to 
     * a dynamically created root virtual file system.
     */
    static final String DYNAMIC_CL_DIR_KEY = "WS-DYNAMIC-CL-DIR";
    
    /**
     * Key used for attaching a URL representing a ref to 
     * a dynamically created root virtual file system.
     */
    static final String DYNAMIC_CL_URL_KEY = "WS-DYNAMIC-CL-URL";
    
    /**
     * Key used for attaching a VirtualFile representing a ref to 
     * a dynamically created WEB-INF/classes virtual file system.
     */
    static final String DYNAMIC_WEBINF_CL_DIR_KEY = "WS-WEBINF-DYNAMIC-CL-DIR";
    
    /**
     * Key used for attaching a URL representing a ref to 
     * a dynamically created WEB-INF/classes virtual file system.
     */
    static final String DYNAMIC_WEBINF_CL_URL_KEY = "WS-WEBINF-DYNAMIC-CL-URL";
    
    /**
     * Sole constructor that performas the following steps:
     * <lu>
     *  <li>Sets the output of this deployer to be {@link EsbMetaData}.</li>
     *  <li>Sets this deployers deployment stage to {@link DeploymentStages#POST_PARSE}./li>
     *  <li>Specifies that this deployer produces JBossWebMetaData and EsbMetaData./li>
     * </lu>
     */
    public EsbWebServiceDeployer()
    {
        super(EsbMetaData.class);
        // Set the deployment stage to after parse.
        setStage(DeploymentStages.POST_PARSE);
        // Tell the MicroContainer that we are producing JBossWebMetaData.
        setOutput(JBossWebMetaData.class);
        // Tell the MicroContainer that we are producing EsbMetaData.
        setOutput(EsbMetaData.class);
    }
    
    @Override
    public void deploy(final VFSDeploymentUnit unit, final EsbMetaData esbMetaData) throws DeploymentException
    {
        boolean webMetaDataCreated = false;
        final JBossWebMetaData webMetaData = new JBossWebMetaData();
        final JBossServletsMetaData servlets = new JBossServletsMetaData();
        final List<ServletMappingMetaData> servletMappings = new ArrayList<ServletMappingMetaData>();
        final FiltersMetaData filters = new FiltersMetaData();
        final List<FilterMappingMetaData> filterMappings = new ArrayList<FilterMappingMetaData>();
        final List<ContractReferencePublisher> publishers = new ArrayList<ContractReferencePublisher>() ;
        final List<SecurityConstraintMetaData> securityConstraintsMDs = new ArrayList<SecurityConstraintMetaData>();
        final WebserviceDescriptionsMetaData descriptions = new WebserviceDescriptionsMetaData();

        final List<WebserviceInfo> webServices = esbMetaData.getModel().getWebserviceServices();
        if (hasWebServices(webServices))
        {
            webMetaDataCreated = true;
            log.debug("Deploying webservices for : " + esbMetaData.getDeploymentName());            

            try
            {
                // Create an in-memory file system.
                final URL inMemRootUrl = VfsUtil.createInMemUrl(esbMetaData.getDeploymentName());
                final VirtualFile inMemRootDir = VfsUtil.createInMemoryFs(inMemRootUrl);
                
                // Attach the in-memory classpath URL and virtual file to this deployment unit so we can remove then upon undeploy.
                //attachToDeploymentUnit(unit, inMemRootUrl, inMemRootDir);
                unit.addAttachment(DYNAMIC_CL_DIR_KEY, inMemRootDir);
                unit.addAttachment(DYNAMIC_CL_URL_KEY, inMemRootUrl);
                
                // Add the in-memory classpath to this deployment unit.
                unit.addClassPath(inMemRootDir);
                
                // Create WEB-INF/classes relative to the in-memory vfs root.
                final URL classesUrl = VfsUtil.createInMemUrl(inMemRootUrl, "WEB-INF/classes");
                final VirtualFile classesDir = MemoryFileFactory.createDirectory(classesUrl);
                unit.addAttachment(DYNAMIC_WEBINF_CL_DIR_KEY, classesDir);
                unit.addAttachment(DYNAMIC_WEBINF_CL_URL_KEY, classesUrl);
                
                // Add the in-memory classes dir to this deployment unit.
                unit.addClassPath(classesDir);
                    
                final JAXWSProviderClassGenerator generator = new JAXWSProviderClassGenerator();
                for (WebserviceInfo wsInfo : webServices)
                {
                    final ESBServiceEndpointInfo serviceInfo = new ESBServiceEndpointInfo(wsInfo);
                    final String handlers = JBossDeployerUtil.getHandlers(serviceInfo);
                    final boolean includeHandlers = handlers != null;
                    if (includeHandlers)
                    {
                        unit.appendMetaDataLocation(classesDir);
                        final String wsHandlerName = serviceInfo.getPackageName().replace('.', '/') + "/esb-jaxws-handlers.xml";
                        VfsUtil.addFile(classesUrl, wsHandlerName, handlers.getBytes());
                    }
                        
                    if (serviceInfo.isOneWay())
                    {
                        FilterMetaData filter = createFilter(serviceInfo);
                        filters.add(filter);
                        filterMappings.add(createFilterMapping(serviceInfo, filter));
                    }
                    
                    final Service service = wsInfo.getService();
                        
                    // Generate the servlet class bytes
                    final byte[] servletClass = generator.generate(service.getCategory(), service.getName(), serviceInfo, includeHandlers);
                    final String servletClassName = serviceInfo.getClassName().replace('.', '/') + ".class";
                    final URL servletClassUrl = VfsUtil.createInMemUrl(classesUrl, servletClassName);
                    
                    // Add the servlet to the virtual file system.
                    VfsUtil.addFile(classesUrl, servletClassName, servletClass);
                    log.debug("Generated ServletImpl '" + servletClassUrl + "'");
                        
                    servlets.add(createServlets(serviceInfo, generator, includeHandlers));
                    servletMappings.add(createServletMapping(serviceInfo));
                    
                    final WebserviceDescriptionMetaData description = new WebserviceDescriptionMetaData();
                    description.setName(esbMetaData.getDeploymentName());
                    description.setWebserviceDescriptionName(esbMetaData.getDeploymentName());
                    description.setWsdlPublishLocation(serviceInfo.getWSDLFileName());
                    descriptions.add(description);
                    
                    final ContractReferencePublisher publisher = new ESBServiceContractReferencePublisher(service, wsInfo.getDescription(), serviceInfo.getServletName());
                    publishers.add(publisher);
                }
            }
            catch (final Exception e)
            {
                throw new DeploymentException("Failed to create webservice artifact", e);
            }
        }

        WebModel webModel = new WebModel(esbMetaData.getArchiveName());
        
        try {
          // Set the global security domain and global security method.
          // These setting are shared for all http-providers and EBWSs 
          // in a jboss-esb.xml file. 
          webModel.setAuthDomain(esbMetaData.getModel().getAuthDomain());
          webModel.setAuthMethod(esbMetaData.getModel().getAuthMethod());
          
            ModelUtil.updateWebModel(ModelUtil.getListenerGroups(esbMetaData.getModel()), webModel);
        } catch (ConfigurationException e) {
            throw new DeploymentException("Failed to capture web metadata from ESB configuration.", e);
        }
        
        // Handle the ServiceContracts
      List<ServiceContract> modelServiceContracts = esbMetaData.getModel().getServiceContracts();
      if (modelServiceContracts != null && modelServiceContracts.size() > 0) {
        List<ServiceContract> actionableServiceContracts = new ArrayList<ServiceContract>();
            for (Servlet servlet : webModel.getServlets()) {
              Service service = servlet.getService();
              String endpointAddress = servlet.getEndpointAddress();
              if (service != null && endpointAddress != null) {
                for (ServiceContract serviceContract : modelServiceContracts) {
                  if (service.equals(serviceContract.getService())) {
                    actionableServiceContracts.add(serviceContract);
                    publishers.add(
                      new DefaultContractReferencePublisher(
                        service, serviceContract.getDescription(), endpointAddress ) );
                    break; // first ServiceContract matching a Servlet wins!
                  }
                }
              }
            }
            esbMetaData.setServiceContracts(actionableServiceContracts);
      }
        
        // Add the filters...
        for(Filter filter : webModel.getFilters()) {
            webMetaDataCreated = true;
            filters.add(createFilter(filter));
            filterMappings.add(createFilterMapping(filter));
        }

        // Add the Servlets...
        for(Servlet servlet : webModel.getServlets()) {
            webMetaDataCreated = true;
            servlets.add(createServlet(servlet));
            servletMappings.add(createServletMapping(servlet));

            SecurityConstraints securityConstraints = servlet.getSecurityConstraints();
            if(securityConstraints != null) {
                SecurityConstraintMetaData securityConstraintMD = new SecurityConstraintMetaData();

                securityConstraintsMDs.add(securityConstraintMD);
                securityConstraintMD.setDisplayName("Constraints for servlet '" + servlet.getName() + "'.");

                // Add the resource details...
                WebResourceCollectionsMetaData resources = new WebResourceCollectionsMetaData();
                WebResourceCollectionMetaData resource = new WebResourceCollectionMetaData();
                resources.add(resource);
                securityConstraintMD.setResourceCollections(resources);
                resource.setHttpMethods(new ArrayList(securityConstraints.getProtectedMethods()));
                resource.setUrlPatterns(servlet.getUrlMappings());

                // Add the Auth Constraint...
                if(!securityConstraints.getAllowedRoles().isEmpty()) {
                    AuthConstraintMetaData constraint = new AuthConstraintMetaData();
                    constraint.setRoleNames(new ArrayList(securityConstraints.getAllowedRoles()));
                    securityConstraintMD.setAuthConstraint(constraint);
                }

                // Add the User Constraint...
                if(securityConstraints.getTransportGuarantee() != null) {
                    UserDataConstraintMetaData constraint = new UserDataConstraintMetaData();
                    constraint.setTransportGuarantee(TransportGuaranteeType.valueOf(securityConstraints.getTransportGuarantee()));
                    securityConstraintMD.setUserDataConstraint(constraint);
                }
            }
        }

        if(webModel.getAuthMethod() != null) {
            LoginConfigMetaData loginConfig = new LoginConfigMetaData();
            loginConfig.setAuthMethod(webModel.getAuthMethod());
            loginConfig.setRealmName("Authentication Realm for '" + esbMetaData.getArchiveName() + "'");
            webMetaData.setLoginConfig(loginConfig);
        }
        if(webModel.getAuthDomain() != null) {
            webMetaData.setSecurityDomain(webModel.getAuthDomain());
        }
        if(!webModel.getSecurityRoles().isEmpty()) {
            SecurityRolesMetaData secRolesMetaData = new SecurityRolesMetaData();
            webMetaData.setSecurityRoles(secRolesMetaData);
            for(String role : webModel.getSecurityRoles()) {
                SecurityRoleMetaData secRoleMetaData = new SecurityRoleMetaData();
                secRoleMetaData.setRoleName(role);
                secRolesMetaData.add(secRoleMetaData);
            }
        }

        if(webMetaDataCreated) {
            webMetaData.setContextRoot(esbMetaData.getDeploymentName());
            webMetaData.setServlets(servlets);
            webMetaData.setServletMappings(servletMappings);
            webMetaData.setFilters(filters);
            webMetaData.setFilterMappings(filterMappings);
            webMetaData.setWebserviceDescriptions(descriptions);
            webMetaData.setSecurityContraints(securityConstraintsMDs);

            esbMetaData.setPublishers(publishers);

            unit.addAttachment(JBossWebMetaData.class, webMetaData);
        }
    }

    @Override
    public void undeploy(final VFSDeploymentUnit unit, final EsbMetaData esbMetaData)
    {
        try
        {
            removeVirtualFile(unit, DYNAMIC_CL_DIR_KEY);
            removeVirtualFile(unit, DYNAMIC_WEBINF_CL_DIR_KEY);
        }
        finally
        {
            try
            {
                removeFromClassPath(unit, DYNAMIC_WEBINF_CL_URL_KEY);
                removeFromClassPath(unit, DYNAMIC_CL_URL_KEY);
            }
            catch (final Exception e)
            {
                log.warn("Error deleting dynamic class root for " + unit.getName(), e);
            }
        }
    }

    private void removeVirtualFile(final VFSDeploymentUnit unit, final String attachmenKey)
    {
        final VirtualFile file = unit.removeAttachment(attachmenKey, VirtualFile.class);
        if (file != null)
        {
            unit.removeClassPath(file);
        }
    }

    private void removeFromClassPath(final VFSDeploymentUnit unit, final String attachmentKey)
    {
        final URL url = unit.removeAttachment(attachmentKey, URL.class);
        if (url != null)
        {
            MemoryFileFactory.delete(url);
        }
    }

    private boolean hasWebServices(final List<WebserviceInfo> endpointServices)
    {
        return endpointServices != null && endpointServices.size() > 0;
    }

    private ServletMappingMetaData createServletMapping(final ESBServiceEndpointInfo serviceInfo)
    {
        final ServletMappingMetaData mapping = new ServletMappingMetaData();
        mapping.setServletName(serviceInfo.getServletName());
        mapping.setUrlPatterns(Arrays.asList(new String[] { "/ebws" + serviceInfo.getServletPath()}));
        return mapping;
    }

    private JBossServletMetaData createServlets(final ESBServiceEndpointInfo serviceInfo, final JAXWSProviderClassGenerator generator, final boolean includeHandlers) throws WebServicePublishException
    {
        final JBossServletMetaData servlet = new JBossServletMetaData();
        servlet.setServletName(serviceInfo.getServletName());
        servlet.setServletClass(serviceInfo.getClassName());
        servlet.setLoadOnStartup(1);
        return servlet;
    }

    private FilterMetaData createFilter(final ESBServiceEndpointInfo serviceInfo)
    {
        // Filter
        final FilterMetaData filter = new FilterMetaData();
        filter.setFilterName(serviceInfo.getServletName() + "_Filter");
        filter.setFilterClass(ESBResponseFilter.class.getName());

        // Set up the initparam 'OneWay'
        final ParamValueMetaData oneWayInitParam = new ParamValueMetaData();
        oneWayInitParam.setParamName("OneWay");
        oneWayInitParam.setParamValue("true");
        filter.setInitParam(Arrays.asList(new ParamValueMetaData[] {oneWayInitParam}));
        return filter;
    }

    private FilterMappingMetaData createFilterMapping(ESBServiceEndpointInfo serviceInfo, FilterMetaData filter) {
        FilterMappingMetaData mapping = new FilterMappingMetaData();
        mapping.setFilterName(filter.getFilterName());
        mapping.setServletNames(Arrays.asList(new String[] {serviceInfo.getServletName()}));
        return mapping;
    }

    private JBossServletMetaData createServlet(Servlet servlet) {
        JBossServletMetaData servletMD = new JBossServletMetaData();

        servletMD.setServletName(servlet.getName());
        servletMD.setServletClass(servlet.getRuntimeClass());
        servletMD.setLoadOnStartup(1);

        List<ParamValueMetaData> initParamsMetaData = createParamsMetaData(servlet.getParams());
        if(initParamsMetaData != null) {
            servletMD.setInitParam(initParamsMetaData);
        }

        return servletMD;
    }

    private ServletMappingMetaData createServletMapping(Servlet servlet) {
        final ServletMappingMetaData mapping = new ServletMappingMetaData();
        mapping.setServletName(servlet.getName());
        mapping.setUrlPatterns(servlet.getUrlMappings());
        return mapping;
    }

    private FilterMetaData createFilter(final Filter filter)
    {
        FilterMetaData filterMetaData = new FilterMetaData();

        filterMetaData.setFilterName(filter.getName());
        filterMetaData.setFilterClass(filter.getRuntimeClass());

        List<ParamValueMetaData> initParamsMetaData = createParamsMetaData(filter.getParams());
        if(initParamsMetaData != null) {
            filterMetaData.setInitParam(initParamsMetaData);
        }

        return filterMetaData;
    }

    private List<ParamValueMetaData> createParamsMetaData(List<KeyValuePair> initParams) {
        List<ParamValueMetaData> initParamsMetaData = null;
        if(!initParams.isEmpty()) {
            initParamsMetaData = new ArrayList<ParamValueMetaData>();
            for(KeyValuePair initParam : initParams) {
                ParamValueMetaData initParamMetaData = new ParamValueMetaData();

                initParamMetaData.setParamName(initParam.getKey());
                initParamMetaData.setParamValue(initParam.getValue());
                initParamsMetaData.add(initParamMetaData);
            }
        }
        return initParamsMetaData;
    }

    private FilterMappingMetaData createFilterMapping(Filter filter) {
        FilterMappingMetaData mapping = new FilterMappingMetaData();
        mapping.setFilterName(filter.getName());
        mapping.setServletNames(Arrays.asList(new String[] {filter.getTargetServlet().getName()}));
        return mapping;
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.