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 package org.apache.oozie.test; 019 020 import org.mortbay.jetty.Server; 021 import org.mortbay.jetty.servlet.FilterHolder; 022 import org.mortbay.jetty.servlet.ServletHolder; 023 import org.mortbay.jetty.servlet.Context; 024 025 import java.net.InetAddress; 026 import java.net.ServerSocket; 027 import java.util.Map; 028 029 /** 030 * An embedded servlet container for testing purposes. <p/> It provides reduced functionality, it supports only 031 * Servlets. <p/> The servlet container is started in a free port. 032 */ 033 public class EmbeddedServletContainer { 034 private Server server; 035 private String host = null; 036 private int port = -1; 037 private String contextPath; 038 Context context; 039 040 /** 041 * Create a servlet container. 042 * 043 * @param contextPath context path for the servlet, it must not be prefixed or append with "/", for the default 044 * context use "" 045 */ 046 public EmbeddedServletContainer(String contextPath) { 047 this.contextPath = contextPath; 048 server = new Server(0); 049 context = new Context(); 050 context.setContextPath("/" + contextPath); 051 server.setHandler(context); 052 } 053 054 /** 055 * Add a servlet to the container. 056 * 057 * @param servletPath servlet path for the servlet, it should be prefixed with '/", it may contain a wild card at 058 * the end. 059 * @param servletClass servlet class 060 * @param initParams a mapping of init parameters for the servlet, or null 061 */ 062 public void addServletEndpoint(String servletPath, Class servletClass, Map<String, String> initParams) { 063 ServletHolder s = new ServletHolder(servletClass); 064 context.addServlet(s, servletPath); 065 if (initParams != null) { 066 s.setInitParameters(initParams); 067 } 068 } 069 070 /** 071 * Add a servlet to the container. 072 * 073 * @param servletPath servlet path for the servlet, it should be prefixed with '/", it may contain a wild card at 074 * the end. 075 * @param servletClass servlet class 076 */ 077 public void addServletEndpoint(String servletPath, Class servletClass) { 078 addServletEndpoint(servletPath, servletClass, null); 079 } 080 081 /** 082 * Add a filter to the container. 083 * 084 * @param filterPath path for the filter, it should be prefixed with '/", it may contain a wild card at 085 * the end. 086 * @param filterClass servlet class 087 */ 088 public void addFilter(String filterPath, Class filterClass) { 089 context.addFilter(new FilterHolder(filterClass), filterPath, 0); 090 } 091 092 /** 093 * Start the servlet container. <p/> The container starts on a free port. 094 * 095 * @throws Exception thrown if the container could not start. 096 */ 097 public void start() throws Exception { 098 host = InetAddress.getLocalHost().getHostName(); 099 ServerSocket ss = new ServerSocket(0); 100 port = ss.getLocalPort(); 101 ss.close(); 102 server.getConnectors()[0].setHost(host); 103 server.getConnectors()[0].setPort(port); 104 server.start(); 105 System.out.println("Running embedded servlet container at: http://" + host + ":" + port); 106 } 107 108 /** 109 * Return the hostname the servlet container is bound to. 110 * 111 * @return the hostname. 112 */ 113 public String getHost() { 114 return host; 115 } 116 117 /** 118 * Return the port number the servlet container is bound to. 119 * 120 * @return the port number. 121 */ 122 public int getPort() { 123 return port; 124 } 125 126 /** 127 * Return the full URL (including protocol, host, port, context path, servlet path) for the context path. 128 * 129 * @return URL to the context path. 130 */ 131 public String getContextURL() { 132 return "http://" + host + ":" + port + "/" + contextPath; 133 } 134 135 /** 136 * Return the full URL (including protocol, host, port, context path, servlet path) for a servlet path. 137 * 138 * @param servletPath the path which will be expanded to a full URL. 139 * @return URL to the servlet. 140 */ 141 public String getServletURL(String servletPath) { 142 String path = servletPath; 143 if (path.endsWith("*")) { 144 path = path.substring(0, path.length() - 1); 145 } 146 return getContextURL() + path; 147 } 148 149 /** 150 * Stop the servlet container. 151 */ 152 public void stop() { 153 try { 154 server.stop(); 155 } 156 catch (Exception e) { 157 // ignore exception 158 } 159 160 try { 161 server.destroy(); 162 } 163 catch (Exception e) { 164 // ignore exception 165 } 166 167 host = null; 168 port = -1; 169 } 170 171 }