import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.thread.ThreadPool;
import org.hibernate.validator.constraints.NotEmpty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.google.common.collect.ImmutableMap;
import io.dropwizard.jetty.ConnectorFactory;
import io.dropwizard.jetty.ContextRoutingHandler;
import io.dropwizard.jetty.HttpConnectorFactory;
import io.dropwizard.server.AbstractServerFactory;
import io.dropwizard.setup.Environment;
/**
* This is an implementation of AbstractServerFactory which allows for distinct HTTP and
* HTTPS Connectors while also running application and admin on the same port within the given
* Connector. It's basically a hybrid of SimpleServerFactory and DefaultServerFactory.
*/
@JsonTypeName("sharedport")
public class SharedPortServerFactory extends AbstractServerFactory
{
private static final Logger LOG = LoggerFactory.getLogger(SharedPortServerFactory.class);
@Valid
@NotNull
private ConnectorFactory connector = HttpConnectorFactory.application();
@Valid
@NotNull
private ConnectorFactory sslConnector = HttpConnectorFactory.application();
@NotEmpty
private String applicationContextPath = "/";
@NotEmpty
private String adminContextPath = "/";
@JsonProperty
public ConnectorFactory getConnector()
{
return connector;
}
@JsonProperty
public void setConnector(ConnectorFactory factory)
{
this.connector = factory;
}
@JsonProperty
public ConnectorFactory getSslConnector()
{
return sslConnector;
}
@JsonProperty
public void setSslConnector(ConnectorFactory sslFactory)
{
this.sslConnector = sslFactory;
}
@JsonProperty
public String getApplicationContextPath()
{
return applicationContextPath;
}
@JsonProperty
public void setApplicationContextPath(String contextPath)
{
this.applicationContextPath = contextPath;
}
@JsonProperty
public String getAdminContextPath()
{
return adminContextPath;
}
@JsonProperty
public void setAdminContextPath(String contextPath)
{
this.adminContextPath = contextPath;
}
@Override
public Server build(Environment environment)
{
printBanner(environment.getName());
ThreadPool threadPool = createThreadPool(environment.metrics());
Server server = buildServer(environment.lifecycle(), threadPool);
LOG.info("Registering jersey handler with root path prefix: {}", applicationContextPath);
environment.getApplicationContext().setContextPath(applicationContextPath);
Handler applicationHandler = createAppServlet(server,
environment.jersey(),
environment.getObjectMapper(),
environment.getValidator(),
environment.getApplicationContext(),
environment.getJerseyServletContainer(),
environment.metrics());
LOG.info("Registering admin handler with root path prefix: {}", adminContextPath);
environment.getAdminContext().setContextPath(adminContextPath);
Handler adminHandler = createAdminServlet(server,
environment.getAdminContext(),
environment.metrics(),
environment.healthChecks());
Connector conn = connector.build(server,
environment.metrics(),
environment.getName(),
null);
Connector sslConn = sslConnector.build(server,
environment.metrics(),
environment.getName(),
null);
server.addConnector(conn);
server.addConnector(sslConn);
ContextRoutingHandler routingHandler = new ContextRoutingHandler(ImmutableMap.of(applicationContextPath, applicationHandler,
adminContextPath, adminHandler));
server.setHandler(addStatsHandler(addRequestLog(server, routingHandler, environment.getName())));
return server;
}
}