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 }