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