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

com.crosstreelabs.testing.JettyServerResource Maven / Gradle / Ivy

There is a newer version: 0.5.0
Show newest version
package com.crosstreelabs.testing;

import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.persist.PersistService;
import com.google.inject.persist.UnitOfWork;
import com.google.inject.persist.jpa.JpaPersistModule;
import com.google.inject.servlet.GuiceFilter;
import com.google.inject.servlet.GuiceServletContextListener;
import com.google.inject.servlet.ServletModule;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.EventListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Singleton;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener;
import org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher;
import org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap;
import org.junit.rules.ExternalResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 */
public class JettyServerResource extends ExternalResource {
    private static final Logger LOG = LoggerFactory.getLogger(JettyServerResource.class);
    private Server server;
    private Injector injector;
    private final int port;
    private boolean withGuice = false;
    private boolean withResteasy = false;
    private String application = null;
    private String withJPA = null;
    private List> filters = new ArrayList<>();
    private String contextPath = null;
    private Map contextParams = new HashMap<>();
    private String resourcePath = null;
    
    public JettyServerResource() {
        this(8080);
    }
    public JettyServerResource(final int port) {
        this.port = port;
    }

    @Override
    protected void before() throws Throwable {
        getServer().start();
    }

    @Override
    protected void after() {
        try {
            server.stop();
        } catch (Exception ex) {}
        server = null;
        injector = null;
    }
    
    //~ Helpers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public Server getServer() {
        if(server == null) {
            server = new Server(port);
            ServletContextHandler servletHandler = new ServletContextHandler();
            for(String name : contextParams.keySet()) {
                servletHandler.getServletContext().setInitParameter(name, contextParams.get(name));
            }
            servletHandler.addEventListener(getEventListener());
            servletHandler.addServlet(getServlet(), "/*").setInitParameters(getServletInitParams());
            if (contextPath != null) {
                servletHandler.setContextPath(contextPath);
            }
            if (resourcePath != null) {
                servletHandler.setResourceBase(resourcePath);
            }
            for (final Class filter : filters) {
                servletHandler.addFilter(filter, "/*", EnumSet.of(DispatcherType.REQUEST));
            }
            server.setHandler(servletHandler);
        }
        return server;
    }
    public EventListener getEventListener() {
        if (withGuice && withResteasy) {
            return getInjector().getInstance(GuiceResteasyBootstrapServletContextListener.class);
        } else if (withGuice) {
            return getInjector().getInstance(GuiceServletContextListener.class);
        } else if (withResteasy) {
            return getInjector().getInstance(ResteasyBootstrap.class);
        }
        throw new IllegalStateException("Cannot divine event listener without guice and resteasy");
    }
    public Class getServlet() {
        return HttpServletDispatcher.class;
    }
    public Map getServletInitParams() {
        Map params = new HashMap<>();
        if (application != null) {
            params.put("javax.ws.rs.Application", application);
        }
        return params;
    }
    public Injector getInjector() {
        if(injector == null) {
            injector = Guice.createInjector(getRootModule());
            if (withJPA != null) {
                injector.getInstance(PersistService.class).start();
            }
        }
        return injector;
    }
    
    //~ Flags ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public JettyServerResource withGuice(final boolean withGuice) {
        this.withGuice = withGuice;
        withFilter(GuiceFilter.class);
        return this;
    }
    public JettyServerResource withResteasy(final boolean withResteasy) {
        this.withResteasy = withResteasy;
        return this;
    }
    public JettyServerResource withResteasyApplication(final String application) {
        withResteasy(true);
        this.application = application;
        return this;
    }
    public JettyServerResource withJPA(final String unitName) {
        this.withJPA = unitName;
        return this;
    }
    public JettyServerResource withContextPath(final String contextPath) {
        LOG.info("Setting context path: "+contextPath);
        this.contextPath = contextPath;
        return this;
    }
    public JettyServerResource withContextParam(final String name, final String value) {
        this.contextParams.put(name, value);
        return this;
    }
    public JettyServerResource withResourcePath(final String resourcePath) {
        LOG.info("Setting resource path: "+resourcePath);
        this.resourcePath = resourcePath;
        return this;
    }
    public JettyServerResource withFilter(final Class filter) {
        filters.add(filter);
        return this;
    }
    
    //~ Helpers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    protected Module[] getRootModule() {
        return new Module[]{new TestModule()};
    }
    protected void getBindings(final Binder binder) {}
    
    /**
     * 
     */
    protected class TestModule extends ServletModule {

        @Override
        protected void configureServlets() {
            if (withJPA != null) {
                filter("/*").through(PersistFilter.class);
                install(new JpaPersistModule(withJPA));
            }
            
            JettyServerResource.this.getBindings(binder());
        }
        
    }    
    
    @Singleton
    public static class PersistFilter implements Filter {
        
        private final UnitOfWork unitOfWork;
        private final PersistService persistService;

        @Inject
        public PersistFilter(UnitOfWork unitOfWork, PersistService persistService) {
            this.unitOfWork = unitOfWork;
            this.persistService = persistService;
        }

        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            try {
                persistService.start();
            } catch (IllegalStateException e) {
                LOG.error("IllegalStateException: "+e);
            }
        }

        @Override
        public void destroy() {
            persistService.stop();
        }

        @Override
        public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
                final FilterChain filterChain) throws IOException, ServletException {
            unitOfWork.begin();
            try {
              filterChain.doFilter(servletRequest, servletResponse);
            } finally {
              unitOfWork.end();
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy