/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
package org.apache.olingo.odata2.testutil.server;
import java.net.BindException;
import java.net.InetSocketAddress;
import java.net.URI;
import javax.servlet.http.HttpServlet;
import org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet;
import org.apache.olingo.odata2.api.ODataService;
import org.apache.olingo.odata2.api.ODataServiceFactory;
import org.apache.olingo.odata2.testutil.fit.FitStaticServiceFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class TestServer {
private static final Logger log = LoggerFactory.getLogger(TestServer.class);
private static final int PORT_MIN = 19000;
private static final int PORT_MAX = 19200;
private static final int PORT_INC = 1;
private static final String DEFAULT_SCHEME = "http";
private static final String DEFAULT_HOST = "localhost";
private static final String DEFAULT_PATH = "/test";
private URI endpoint; // = URI.create("http://localhost:19080/test"); // no slash at the end !!!
private final String path;
private int pathSplit = 0;
private ServletType servletType;
public TestServer(ServletType type) {
this(DEFAULT_PATH, type);
}
public TestServer(final String path, ServletType type) {
if (path.startsWith("/")) {
this.path = path;
} else {
this.path = "/" + path;
}
this.servletType = type;
}
public int getPathSplit() {
return pathSplit;
}
public void setPathSplit(final int pathSplit) {
this.pathSplit = pathSplit;
}
public URI getEndpoint() {
return URI.create(endpoint + "/");
}
private Server server;
public void startServer(final Class<? extends ODataServiceFactory> factoryClass, final int fixedPort) {
try {
final ServletContextHandler contextHandler = createContextHandler(factoryClass);
final InetSocketAddress isa = new InetSocketAddress(DEFAULT_HOST, fixedPort);
server = new Server(isa);
server.setHandler(contextHandler);
server.start();
endpoint = new URI(DEFAULT_SCHEME, null, DEFAULT_HOST, isa.getPort(), "/abc" + path, null, null);
log.trace("Started server at endpoint " + endpoint.toASCIIString());
} catch (final Exception e) {
log.error("server start failed", e);
throw new ServerRuntimeException(e);
}
}
public void startServer(final Class<? extends ODataServiceFactory> factoryClass) {
try {
for (int port = PORT_MIN; port <= PORT_MAX; port += PORT_INC) {
final ServletContextHandler contextHandler = createContextHandler(factoryClass);
try {
final InetSocketAddress isa = new InetSocketAddress(DEFAULT_HOST, port);
server = new Server(isa);
server.setHandler(contextHandler);
server.start();
endpoint = new URI(DEFAULT_SCHEME, null, DEFAULT_HOST, isa.getPort(), "/abc" + path, null, null);
log.trace("Started server at endpoint " + endpoint.toASCIIString());
break;
} catch (final BindException e) {
log.trace("port is busy... " + port + " [" + e.getMessage() + "]");
}
}
if (!server.isStarted()) {
throw new BindException("no free port in range of [" + PORT_MIN + ".." + PORT_MAX + "]");
}
} catch (final Exception e) {
log.error("server start failed", e);
throw new ServerRuntimeException(e);
}
}
private ServletContextHandler createContextHandler(final Class<? extends ODataServiceFactory> factoryClass)
throws Exception {
ServletHolder odataServletHolder = null;
switch (servletType) {
case JAXRS_SERVLET:
odataServletHolder = new ServletHolder(new CXFNonSpringJaxrsServlet());
odataServletHolder.setInitParameter("javax.ws.rs.Application",
"org.apache.olingo.odata2.core.rest.app.ODataApplication");
odataServletHolder.setInitParameter(ODataServiceFactory.FACTORY_LABEL, factoryClass.getCanonicalName());
break;
case ODATA_SERVLET:
String odataServlet = "org.apache.olingo.odata2.core.servlet.ODataServlet";
final HttpServlet httpServlet = (HttpServlet) Class.forName(odataServlet).newInstance();
odataServletHolder = new ServletHolder(httpServlet);
odataServletHolder.setInitParameter(ODataServiceFactory.FACTORY_LABEL, factoryClass.getCanonicalName());
break;
default:
}
if (pathSplit > 0) {
odataServletHolder.setInitParameter(ODataServiceFactory.PATH_SPLIT_LABEL, Integer.toString(pathSplit));
}
final ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
contextHandler.setContextPath("/abc");
contextHandler.addServlet(odataServletHolder, path + "/*");
return contextHandler;
}
// private ServletContextHandler createODataContextHandler(final Class<? extends ODataServiceFactory> factoryClass)
// throws InstantiationException, IllegalAccessException, ClassNotFoundException {
// String odataServlet = "org.apache.olingo.odata2.core.servlet.ODataServlet";
// final HttpServlet httpServlet = (HttpServlet) Class.forName(odataServlet).newInstance();
// final ServletHolder odataServletHolder = new ServletHolder(httpServlet);
// odataServletHolder.setInitParameter(ODataServiceFactory.FACTORY_LABEL, factoryClass.getCanonicalName());
//
// if (pathSplit > 0) {
// odataServletHolder.setInitParameter(ODataServiceFactory.PATH_SPLIT_LABEL, Integer.toString(pathSplit));
// }
//
// final ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
// contextHandler.setContextPath("/abc");
// contextHandler.addServlet(odataServletHolder, path + "/*");
// return contextHandler;
// }
public void startServer(final ODataService service) {
startServer(FitStaticServiceFactory.class);
if ((server != null) && server.isStarted()) {
FitStaticServiceFactory.bindService(this, service);
}
}
public void stopServer() {
try {
if (server != null) {
FitStaticServiceFactory.unbindService(this);
server.stop();
log.trace("Stopped server at endpoint " + getEndpoint().toASCIIString());
}
} catch (final Exception e) {
throw new ServerRuntimeException(e);
}
}
}