All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.consol.citrus.ws.server.WebServiceServer Maven / Gradle / Ivy

There is a newer version: 3.4.1
Show newest version
/*
 * Copyright 2006-2010 the original author or authors.
 *
 * 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 com.consol.citrus.ws.server;

import com.consol.citrus.exceptions.CitrusRuntimeException;
import com.consol.citrus.server.AbstractServer;
import com.consol.citrus.ws.message.converter.SoapMessageConverter;
import com.consol.citrus.ws.message.converter.WebServiceMessageConverter;
import com.consol.citrus.ws.servlet.CitrusMessageDispatcherServlet;
import org.eclipse.jetty.security.SecurityHandler;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.*;
import org.eclipse.jetty.servlet.*;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.*;
import org.springframework.core.ResolvableType;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.ws.transport.http.MessageDispatcherServlet;

import javax.servlet.ServletContext;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.*;

/**
 * Jetty server implementation wrapping a {@link Server} with Citrus server behaviour, so
 * server can be started/stopped by Citrus.
 * 
 * @author Christoph Deppisch
 */
public class WebServiceServer extends AbstractServer implements ApplicationContextAware {

    /** Server port */
    private int port = 8080;
    
    /** Server resource base */
    private String resourceBase = "src/main/resources";
    
    /** Application context location for payload mappings etc. */
    private String contextConfigLocation = "classpath:com/consol/citrus/ws/citrus-servlet-context.xml";
    
    /** Server instance to be wrapped */
    private Server jettyServer;

    /** Application context used as delegate for parent WebApplicationContext in Jetty */
    private ApplicationContext applicationContext;
    
    /** Use root application context as parent to build WebApplicationContext */
    private boolean useRootContextAsParent = false;
    
    /** Do only start one instance after another so we need a static lock object */
    private static Object serverLock = new Object();
    
    /** Set custom connector with custom idle time and other configuration options */
    private Connector connector;
    
    /** Set list of custom connectors with custom configuration options */
    private Connector[] connectors;
    
    /** Servlet mapping path */
    private String servletMappingPath = "/*";
    
    /** Optional servlet name customization */
    private String servletName;
    
    /** Context path */
    private String contextPath = "/";
    
    /** Optional security handler for basic auth */
    private SecurityHandler securityHandler;
    
    /** Optional servlet handler customization */
    private ServletHandler servletHandler;

    /** Should handle Http mime headers */
    private boolean handleMimeHeaders = false;

    /** Should keep soap envelope when creating internal message */
    private boolean keepSoapEnvelope = false;

    /** Message converter implementation */
    private WebServiceMessageConverter messageConverter = new SoapMessageConverter();

    /** Web service message factory bean name */
    private String messageFactoryName = MessageDispatcherServlet.DEFAULT_MESSAGE_FACTORY_BEAN_NAME;

    /** Default SOAP header namespace and prefix */
    private String soapHeaderNamespace;
    private String soapHeaderPrefix = "";
    
    @Override
    protected void shutdown() {
        if (jettyServer != null) {
            try {
                synchronized (serverLock) {
                    jettyServer.stop();
                }
            } catch (Exception e) {
                throw new CitrusRuntimeException(e);
            }
        }
    }

    @Override
    protected void startup() {
        synchronized (serverLock) {
            if (connectors != null && connectors.length > 0) {
                jettyServer = connectors[0].getServer();
                jettyServer.setConnectors(connectors);
            } else if (connector != null) {
                jettyServer = connector.getServer();
                jettyServer.addConnector(connector);
            } else {
                jettyServer = new Server(port);
            }
            
            HandlerCollection handlers = new HandlerCollection();
            
            ContextHandlerCollection contextCollection = new ContextHandlerCollection();
            
            ServletContextHandler contextHandler = new ServletContextHandler();
            contextHandler.setContextPath(contextPath);
            contextHandler.setResourceBase(resourceBase);
            
            //add the root application context as parent to the constructed WebApplicationContext
            if (useRootContextAsParent) {
                contextHandler.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, 
                        new SimpleDelegatingWebApplicationContext());
            }
            
            if (servletHandler == null) {
                servletHandler = new ServletHandler();
                addDispatcherServlet();
            }
            
            contextHandler.setServletHandler(servletHandler);
            
            if (securityHandler != null) {
                contextHandler.setSecurityHandler(securityHandler);
            }
            
            contextCollection.addHandler(contextHandler);
            
            handlers.addHandler(contextCollection);
            
            handlers.addHandler(new DefaultHandler());
            handlers.addHandler(new RequestLogHandler());
            
            jettyServer.setHandler(handlers);
            
            try {
                jettyServer.start();
            } catch (Exception e) {
                throw new CitrusRuntimeException(e);
            }
        }
    }

    /**
     * Adds Citrus message dispatcher servlet.
     */
    private void addDispatcherServlet() {
        ServletHolder servletHolder = new ServletHolder(new CitrusMessageDispatcherServlet(this));
        servletHolder.setName(getServletName());
        servletHolder.setInitParameter("contextConfigLocation", contextConfigLocation);

        servletHandler.addServlet(servletHolder);

        ServletMapping servletMapping = new ServletMapping();
        servletMapping.setServletName(getServletName());
        servletMapping.setPathSpec(servletMappingPath);

        servletHandler.addServletMapping(servletMapping);
    }

    /**
     * Gets the customized servlet name or default name if not set.
     * @return the servletName
     */
    public String getServletName() {
        if (StringUtils.hasText(servletName)) {
            return servletName;
        } else {
            return getName() + "-servlet";
        }
    }

    /**
     * WebApplicationContext implementation that delegates method calls to parent ApplicationContext.
     */
    private final class SimpleDelegatingWebApplicationContext implements WebApplicationContext {
        public Resource getResource(String location) {
            return applicationContext.getResource(location);
        }
        public ClassLoader getClassLoader() {
            return applicationContext.getClassLoader();
        }
        public Resource[] getResources(String locationPattern) throws IOException {
            return applicationContext.getResources(locationPattern);
        }
        public void publishEvent(ApplicationEvent event) {
            applicationContext.publishEvent(event);
        }
        public void publishEvent(Object event) { applicationContext.publishEvent(event); }
        public String getMessage(String code, Object[] args, String defaultMessage,
                Locale locale) {
            return applicationContext.getMessage(code, args, defaultMessage, locale);
        }
        public String getMessage(String code, Object[] args, Locale locale)
                throws NoSuchMessageException {
            return applicationContext.getMessage(code, args, locale);
        }
        public String getMessage(MessageSourceResolvable resolvable, Locale locale)
                throws NoSuchMessageException {
            return applicationContext.getMessage(resolvable, locale);
        }
        public BeanFactory getParentBeanFactory() {
            return applicationContext.getParentBeanFactory();
        }
        public boolean containsLocalBean(String name) {
            return applicationContext.containsBean(name);
        }
        public boolean isSingleton(String name)
                throws NoSuchBeanDefinitionException {
            return applicationContext.isSingleton(name);
        }
        public boolean isPrototype(String name)
                throws NoSuchBeanDefinitionException {
            return applicationContext.isPrototype(name);
        }
        public Object getBean(String name) throws BeansException {
            return applicationContext.getBean(name);
        }
        public String[] getAliases(String name) {
            return applicationContext.getAliases(name);
        }
        public boolean containsBean(String name) {
            return applicationContext.containsBean(name);
        }
        public String[] getBeanDefinitionNames() {
            return applicationContext.getBeanDefinitionNames();
        }
        public String[] getBeanNamesForType(ResolvableType type) {
            return applicationContext.getBeanNamesForType(type);
        }
        public int getBeanDefinitionCount() {
            return applicationContext.getBeanDefinitionCount();
        }
        public boolean containsBeanDefinition(String beanName) {
            return applicationContext.containsBeanDefinition(beanName);
        }
        public long getStartupDate() {
            return applicationContext.getStartupDate();
        }
        public ApplicationContext getParent() {
            return applicationContext.getParent();
        }
        public String getId() {
            return applicationContext.getId();
        }
        public String getApplicationName() {
            return applicationContext.getApplicationName();
        }
        public String getDisplayName() {
            return applicationContext.getDisplayName();
        }
        public AutowireCapableBeanFactory getAutowireCapableBeanFactory()
                throws IllegalStateException {
            return applicationContext.getAutowireCapableBeanFactory();
        }
        public  Map getBeansOfType(Class type)
                throws BeansException {
            return applicationContext.getBeansOfType(type);
        }
        public  Map getBeansOfType(Class type,
                boolean includeNonSingletons, boolean allowEagerInit)
                throws BeansException {
            return applicationContext.getBeansOfType(type, includeNonSingletons, allowEagerInit);
        }

        public String[] getBeanNamesForAnnotation(Class annotationType) {
            return applicationContext.getBeanNamesForAnnotation(annotationType);
        }

        public Map getBeansWithAnnotation(
                Class annotationType)
                throws BeansException {
            return applicationContext.getBeansWithAnnotation(annotationType);
        }
        public  A findAnnotationOnBean(String beanName,
                Class annotationType) {
            return applicationContext.findAnnotationOnBean(beanName, annotationType);
        }
        public  T getBean(String name, Class requiredType)
                throws BeansException {
            return applicationContext.getBean(name, requiredType);
        }
        public  T getBean(Class requiredType) throws BeansException {
            return applicationContext.getBean(requiredType);
        }
        public String[] getBeanNamesForType(Class type) {
            return applicationContext.getBeanNamesForType(type);
        }
        public String[] getBeanNamesForType(Class type,
                boolean includeNonSingletons, boolean allowEagerInit) {
            return applicationContext.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
        }
        public Object getBean(String name, Object... args)
                throws BeansException {
            return applicationContext.getBean(name, args);
        }
        public  T getBean(Class requiredType, Object... args) throws BeansException {
            return applicationContext.getBean(requiredType, args);
        }
        public boolean isTypeMatch(String name, Class targetType)
                throws NoSuchBeanDefinitionException {
            return applicationContext.isTypeMatch(name, targetType);
        }
        public boolean isTypeMatch(String name, ResolvableType targetType)
                throws NoSuchBeanDefinitionException {
            return applicationContext.isTypeMatch(name, targetType);
        }
        public Class getType(String name)
                throws NoSuchBeanDefinitionException {
            return applicationContext.getType(name);
        }
        public ServletContext getServletContext() {
            return null;
        }
        public Environment getEnvironment() {
            return applicationContext.getEnvironment();
        }
    }

    /**
     * {@inheritDoc}
     */
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * Gets the port.
     * @return the port the port to get.
     */
    public int getPort() {
        return port;
    }

    /**
     * Sets the port.
     * @param port the port to set
     */
    public void setPort(int port) {
        this.port = port;
    }

    /**
     * Gets the resourceBase.
     * @return the resourceBase the resourceBase to get.
     */
    public String getResourceBase() {
        return resourceBase;
    }

    /**
     * Sets the resourceBase.
     * @param resourceBase the resourceBase to set
     */
    public void setResourceBase(String resourceBase) {
        this.resourceBase = resourceBase;
    }

    /**
     * Gets the contextConfigLocation.
     * @return the contextConfigLocation the contextConfigLocation to get.
     */
    public String getContextConfigLocation() {
        return contextConfigLocation;
    }

    /**
     * Sets the contextConfigLocation.
     * @param contextConfigLocation the contextConfigLocation to set
     */
    public void setContextConfigLocation(String contextConfigLocation) {
        this.contextConfigLocation = contextConfigLocation;
    }

    /**
     * Gets the connector.
     * @return the connector the connector to get.
     */
    public Connector getConnector() {
        return connector;
    }

    /**
     * Sets the connector.
     * @param connector the connector to set
     */
    public void setConnector(Connector connector) {
        this.connector = connector;
    }

    /**
     * Gets the connectors.
     * @return the connectors
     */
    public Connector[] getConnectors() {
        if (connectors != null) {
            return Arrays.copyOf(connectors, connectors.length);
        } else {
            return new Connector[]{};
        }
    }

    /**
     * Sets the connectors.
     * @param connectors the connectors to set
     */
    public void setConnectors(Connector[] connectors) {
        this.connectors = Arrays.copyOf(connectors, connectors.length);
    }

    /**
     * Gets the servletMappingPath.
     * @return the servletMappingPath the servletMappingPath to get.
     */
    public String getServletMappingPath() {
        return servletMappingPath;
    }

    /**
     * Sets the servletMappingPath.
     * @param servletMappingPath the servletMappingPath to set
     */
    public void setServletMappingPath(String servletMappingPath) {
        this.servletMappingPath = servletMappingPath;
    }

    /**
     * Gets the contextPath.
     * @return the contextPath the contextPath to get.
     */
    public String getContextPath() {
        return contextPath;
    }

    /**
     * Sets the contextPath.
     * @param contextPath the contextPath to set
     */
    public void setContextPath(String contextPath) {
        this.contextPath = contextPath;
    }

    /**
     * Gets the securityHandler.
     * @return the securityHandler the securityHandler to get.
     */
    public SecurityHandler getSecurityHandler() {
        return securityHandler;
    }

    /**
     * Sets the securityHandler.
     * @param securityHandler the securityHandler to set
     */
    public void setSecurityHandler(SecurityHandler securityHandler) {
        this.securityHandler = securityHandler;
    }

    /**
     * Gets the servletHandler.
     * @return the servletHandler the servletHandler to get.
     */
    public ServletHandler getServletHandler() {
        return servletHandler;
    }

    /**
     * Sets the servletHandler.
     * @param servletHandler the servletHandler to set
     */
    public void setServletHandler(ServletHandler servletHandler) {
        this.servletHandler = servletHandler;
    }

    /**
     * Sets the servletName.
     * @param servletName the servletName to set
     */
    public void setServletName(String servletName) {
        this.servletName = servletName;
    }

    /**
     * Gets the useRootContextAsParent.
     * @return the useRootContextAsParent the useRootContextAsParent to get.
     */
    public boolean isUseRootContextAsParent() {
        return useRootContextAsParent;
    }

    /**
     * Sets the useRootContextAsParent.
     * @param useRootContextAsParent the useRootContextAsParent to set
     */
    public void setUseRootContextAsParent(boolean useRootContextAsParent) {
        this.useRootContextAsParent = useRootContextAsParent;
    }

    /**
     * Should handle mime headers.
     * @return
     */
    public boolean isHandleMimeHeaders() {
        return handleMimeHeaders;
    }

    /**
     * Enable mime headers in request message which is passed to endpoint adapter.
     * @param handleMimeHeaders the handleMimeHeaders to set
     */
    public void setHandleMimeHeaders(boolean handleMimeHeaders) {
        this.handleMimeHeaders = handleMimeHeaders;
    }

    /**
     * Gets the keep soap envelope flag.
     * @return
     */
    public boolean isKeepSoapEnvelope() {
        return keepSoapEnvelope;
    }

    /**
     * Sets the keep soap header flag.
     * @param keepSoapEnvelope
     */
    public void setKeepSoapEnvelope(boolean keepSoapEnvelope) {
        this.keepSoapEnvelope = keepSoapEnvelope;
    }

    /**
     * Gets the default soap header namespace.
     * @return
     */
    public String getSoapHeaderNamespace() {
        return soapHeaderNamespace;
    }

    /**
     * Sets the default soap header namespace.
     * @param soapHeaderNamespace
     */
    public void setSoapHeaderNamespace(String soapHeaderNamespace) {
        this.soapHeaderNamespace = soapHeaderNamespace;
    }

    /**
     * Gets the default soap header prefix.
     * @return
     */
    public String getSoapHeaderPrefix() {
        return soapHeaderPrefix;
    }

    /**
     * Sets the default soap header prefix.
     * @param soapHeaderPrefix
     */
    public void setSoapHeaderPrefix(String soapHeaderPrefix) {
        this.soapHeaderPrefix = soapHeaderPrefix;
    }

    /**
     * Gets the message converter.
     * @return
     */
    public WebServiceMessageConverter getMessageConverter() {
        return messageConverter;
    }

    /**
     * Sets the message converter.
     * @param messageConverter
     */
    public void setMessageConverter(WebServiceMessageConverter messageConverter) {
        this.messageConverter = messageConverter;
    }

    /**
     * Gets the message factory name.
     * @return
     */
    public String getMessageFactoryName() {
        return messageFactoryName;
    }

    /**
     * Sets the message factory name.
     * @param messageFactoryName
     */
    public void setMessageFactoryName(String messageFactoryName) {
        this.messageFactoryName = messageFactoryName;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy