001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.oozie.test; 020 021import org.mortbay.jetty.Server; 022import org.mortbay.jetty.servlet.FilterHolder; 023import org.mortbay.jetty.servlet.ServletHolder; 024import org.mortbay.jetty.servlet.Context; 025 026import java.net.InetAddress; 027import java.net.ServerSocket; 028import java.util.Map; 029 030/** 031 * An embedded servlet container for testing purposes. <p/> It provides reduced functionality, it supports only 032 * Servlets. <p/> The servlet container is started in a free port. 033 */ 034public class EmbeddedServletContainer { 035 private Server server; 036 private String host = null; 037 private int port = -1; 038 private String contextPath; 039 Context context; 040 041 /** 042 * Create a servlet container. 043 * 044 * @param contextPath context path for the servlet, it must not be prefixed or append with "/", for the default 045 * context use "" 046 */ 047 public EmbeddedServletContainer(String contextPath) { 048 this.contextPath = contextPath; 049 server = new Server(0); 050 context = new Context(); 051 context.setContextPath("/" + contextPath); 052 server.setHandler(context); 053 } 054 055 /** 056 * Add a servlet to the container. 057 * 058 * @param servletPath servlet path for the servlet, it should be prefixed with '/", it may contain a wild card at 059 * the end. 060 * @param servletClass servlet class 061 * @param initParams a mapping of init parameters for the servlet, or null 062 */ 063 public void addServletEndpoint(String servletPath, Class servletClass, Map<String, String> initParams) { 064 ServletHolder s = new ServletHolder(servletClass); 065 context.addServlet(s, servletPath); 066 if (initParams != null) { 067 s.setInitParameters(initParams); 068 } 069 } 070 071 /** 072 * Add a servlet to the container. 073 * 074 * @param servletPath servlet path for the servlet, it should be prefixed with '/", it may contain a wild card at 075 * the end. 076 * @param servletClass servlet class 077 */ 078 public void addServletEndpoint(String servletPath, Class servletClass) { 079 addServletEndpoint(servletPath, servletClass, null); 080 } 081 082 /** 083 * Add a filter to the container. 084 * 085 * @param filterPath path for the filter, it should be prefixed with '/", it may contain a wild card at 086 * the end. 087 * @param filterClass servlet class 088 */ 089 public void addFilter(String filterPath, Class filterClass) { 090 context.addFilter(new FilterHolder(filterClass), filterPath, 0); 091 } 092 093 /** 094 * Start the servlet container. <p/> The container starts on a free port. 095 * 096 * @throws Exception thrown if the container could not start. 097 */ 098 public void start() throws Exception { 099 host = InetAddress.getLocalHost().getHostName(); 100 ServerSocket ss = new ServerSocket(0); 101 port = ss.getLocalPort(); 102 ss.close(); 103 server.getConnectors()[0].setHost(host); 104 server.getConnectors()[0].setPort(port); 105 server.start(); 106 System.out.println("Running embedded servlet container at: http://" + host + ":" + port); 107 } 108 109 /** 110 * Return the hostname the servlet container is bound to. 111 * 112 * @return the hostname. 113 */ 114 public String getHost() { 115 return host; 116 } 117 118 /** 119 * Return the port number the servlet container is bound to. 120 * 121 * @return the port number. 122 */ 123 public int getPort() { 124 return port; 125 } 126 127 /** 128 * Return the full URL (including protocol, host, port, context path, servlet path) for the context path. 129 * 130 * @return URL to the context path. 131 */ 132 public String getContextURL() { 133 return "http://" + host + ":" + port + "/" + contextPath; 134 } 135 136 /** 137 * Return the full URL (including protocol, host, port, context path, servlet path) for a servlet path. 138 * 139 * @param servletPath the path which will be expanded to a full URL. 140 * @return URL to the servlet. 141 */ 142 public String getServletURL(String servletPath) { 143 String path = servletPath; 144 if (path.endsWith("*")) { 145 path = path.substring(0, path.length() - 1); 146 } 147 return getContextURL() + path; 148 } 149 150 /** 151 * Stop the servlet container. 152 */ 153 public void stop() { 154 try { 155 server.stop(); 156 } 157 catch (Exception e) { 158 // ignore exception 159 } 160 161 try { 162 server.destroy(); 163 } 164 catch (Exception e) { 165 // ignore exception 166 } 167 168 host = null; 169 port = -1; 170 } 171 172}