mirror of https://github.com/apache/druid.git
Merge pull request #1167 from himanshug/servlet_filter_holder2
feature to add servlet filters in a druid node via extension modules
This commit is contained in:
commit
bfe61703f5
|
@ -55,7 +55,7 @@ import io.druid.guice.annotations.Json;
|
||||||
import io.druid.guice.annotations.Smile;
|
import io.druid.guice.annotations.Smile;
|
||||||
import io.druid.guice.http.HttpClientModule;
|
import io.druid.guice.http.HttpClientModule;
|
||||||
import io.druid.server.initialization.EmitterModule;
|
import io.druid.server.initialization.EmitterModule;
|
||||||
import io.druid.server.initialization.JettyServerModule;
|
import io.druid.server.initialization.jetty.JettyServerModule;
|
||||||
import io.druid.server.metrics.MetricsModule;
|
import io.druid.server.metrics.MetricsModule;
|
||||||
import io.tesla.aether.Repository;
|
import io.tesla.aether.Repository;
|
||||||
import io.tesla.aether.TeslaAether;
|
import io.tesla.aether.TeslaAether;
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
* Druid - a distributed column store.
|
|
||||||
* Copyright 2012 - 2015 Metamarkets Group Inc.
|
|
||||||
*
|
|
||||||
* Licensed 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 io.druid.server.initialization;
|
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
|
||||||
import org.eclipse.jetty.servlet.FilterHolder;
|
|
||||||
import org.eclipse.jetty.servlets.AsyncGzipFilter;
|
|
||||||
import org.eclipse.jetty.servlets.GzipFilter;
|
|
||||||
|
|
||||||
import javax.ws.rs.HttpMethod;
|
|
||||||
|
|
||||||
public abstract class BaseJettyServerInitializer implements JettyServerInitializer
|
|
||||||
{
|
|
||||||
|
|
||||||
public static final String GZIP_METHODS = Joiner.on(",").join(HttpMethod.GET, HttpMethod.POST);
|
|
||||||
|
|
||||||
public FilterHolder defaultGzipFilterHolder()
|
|
||||||
{
|
|
||||||
final FilterHolder gzipFilterHolder = new FilterHolder(GzipFilter.class);
|
|
||||||
setDefaultGzipFilterHolderParameters(gzipFilterHolder);
|
|
||||||
return gzipFilterHolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FilterHolder defaultAsyncGzipFilterHolder()
|
|
||||||
{
|
|
||||||
final FilterHolder gzipFilterHolder = new FilterHolder(AsyncGzipFilter.class);
|
|
||||||
setDefaultGzipFilterHolderParameters(gzipFilterHolder);
|
|
||||||
return gzipFilterHolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setDefaultGzipFilterHolderParameters(final FilterHolder filterHolder)
|
|
||||||
{
|
|
||||||
filterHolder.setInitParameter("minGzipSize", "0");
|
|
||||||
filterHolder.setInitParameter("methods", GZIP_METHODS);
|
|
||||||
|
|
||||||
// We don't actually have any precomputed .gz resources, and checking for them inside jars is expensive.
|
|
||||||
filterHolder.setInitParameter("checkGzExists", String.valueOf(false));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Metamarkets Group Inc. (Metamarkets) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. Metamarkets 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 io.druid.server.initialization.jetty;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Key;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
import com.metamx.common.ISE;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.servlet.FilterHolder;
|
||||||
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
|
import org.eclipse.jetty.servlets.AsyncGzipFilter;
|
||||||
|
import org.eclipse.jetty.servlets.GzipFilter;
|
||||||
|
|
||||||
|
import javax.ws.rs.HttpMethod;
|
||||||
|
|
||||||
|
public class JettyServerInitUtils
|
||||||
|
{
|
||||||
|
|
||||||
|
public static final String GZIP_METHODS = Joiner.on(",").join(HttpMethod.GET, HttpMethod.POST);
|
||||||
|
|
||||||
|
public static FilterHolder defaultGzipFilterHolder()
|
||||||
|
{
|
||||||
|
final FilterHolder gzipFilterHolder = new FilterHolder(GzipFilter.class);
|
||||||
|
setDefaultGzipFilterHolderParameters(gzipFilterHolder);
|
||||||
|
return gzipFilterHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FilterHolder defaultAsyncGzipFilterHolder()
|
||||||
|
{
|
||||||
|
final FilterHolder gzipFilterHolder = new FilterHolder(AsyncGzipFilter.class);
|
||||||
|
setDefaultGzipFilterHolderParameters(gzipFilterHolder);
|
||||||
|
return gzipFilterHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setDefaultGzipFilterHolderParameters(final FilterHolder filterHolder)
|
||||||
|
{
|
||||||
|
filterHolder.setInitParameter("minGzipSize", "0");
|
||||||
|
filterHolder.setInitParameter("methods", GZIP_METHODS);
|
||||||
|
|
||||||
|
// We don't actually have any precomputed .gz resources, and checking for them inside jars is expensive.
|
||||||
|
filterHolder.setInitParameter("checkGzExists", String.valueOf(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addExtensionFilters(ServletContextHandler handler, Injector injector) {
|
||||||
|
Set<ServletFilterHolder> extensionFilters = injector.getInstance(Key.get(new TypeLiteral<Set<ServletFilterHolder>>(){}));
|
||||||
|
|
||||||
|
for (ServletFilterHolder servletFilterHolder : extensionFilters) {
|
||||||
|
// Check the Filter first to guard against people who don't read the docs and return the Class even
|
||||||
|
// when they have an instance.
|
||||||
|
FilterHolder holder = null;
|
||||||
|
if (servletFilterHolder.getFilter() != null) {
|
||||||
|
holder = new FilterHolder(servletFilterHolder.getFilter());
|
||||||
|
} else if (servletFilterHolder.getFilterClass() != null) {
|
||||||
|
holder = new FilterHolder(servletFilterHolder.getFilterClass());
|
||||||
|
} else {
|
||||||
|
throw new ISE("Filter[%s] for path[%s] didn't have a Filter!?", servletFilterHolder, servletFilterHolder.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(servletFilterHolder.getInitParameters() != null) {
|
||||||
|
holder.setInitParameters(servletFilterHolder.getInitParameters());
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.addFilter(holder, servletFilterHolder.getPath(), servletFilterHolder.getDispatcherType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.druid.server.initialization;
|
package io.druid.server.initialization.jetty;
|
||||||
|
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.druid.server.initialization;
|
package io.druid.server.initialization.jetty;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
|
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
|
||||||
|
@ -29,6 +29,7 @@ import com.google.inject.Provides;
|
||||||
import com.google.inject.ProvisionException;
|
import com.google.inject.ProvisionException;
|
||||||
import com.google.inject.Scopes;
|
import com.google.inject.Scopes;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
import com.google.inject.multibindings.Multibinder;
|
||||||
import com.metamx.common.lifecycle.Lifecycle;
|
import com.metamx.common.lifecycle.Lifecycle;
|
||||||
import com.metamx.common.logger.Logger;
|
import com.metamx.common.logger.Logger;
|
||||||
import com.sun.jersey.api.core.DefaultResourceConfig;
|
import com.sun.jersey.api.core.DefaultResourceConfig;
|
||||||
|
@ -44,6 +45,8 @@ import io.druid.guice.annotations.Json;
|
||||||
import io.druid.guice.annotations.Self;
|
import io.druid.guice.annotations.Self;
|
||||||
import io.druid.server.DruidNode;
|
import io.druid.server.DruidNode;
|
||||||
import io.druid.server.StatusResource;
|
import io.druid.server.StatusResource;
|
||||||
|
import io.druid.server.initialization.ServerConfig;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Connector;
|
import org.eclipse.jetty.server.Connector;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
import org.eclipse.jetty.server.ServerConnector;
|
||||||
|
@ -72,6 +75,10 @@ public class JettyServerModule extends JerseyServletModule
|
||||||
|
|
||||||
Jerseys.addResource(binder, StatusResource.class);
|
Jerseys.addResource(binder, StatusResource.class);
|
||||||
binder.bind(StatusResource.class).in(LazySingleton.class);
|
binder.bind(StatusResource.class).in(LazySingleton.class);
|
||||||
|
|
||||||
|
//Adding empty binding for ServletFilterHolders so that injector returns
|
||||||
|
//an empty set when no external modules provide ServletFilterHolder impls
|
||||||
|
Multibinder.newSetBinder(binder, ServletFilterHolder.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class DruidGuiceContainer extends GuiceContainer
|
public static class DruidGuiceContainer extends GuiceContainer
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Metamarkets Group Inc. (Metamarkets) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. Metamarkets 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 io.druid.server.initialization.jetty;
|
||||||
|
|
||||||
|
import javax.servlet.DispatcherType;
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ServletFilterHolder is a class that holds all of the information required to attach a Filter to a Servlet.
|
||||||
|
*
|
||||||
|
* This largely exists just to make it possible to add Filters via Guice/DI and shouldn't really exist
|
||||||
|
* anywhere that is not initialization code.
|
||||||
|
*
|
||||||
|
* Note that some of the druid nodes (router for example) use async servlets and your filter
|
||||||
|
* implementation should be able to handle those requests properly.
|
||||||
|
*/
|
||||||
|
public interface ServletFilterHolder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Filter object that should be added to the servlet.
|
||||||
|
*
|
||||||
|
* This method is considered "mutually exclusive" from the getFilterClass method.
|
||||||
|
* That is, one of them should return null and the other should return an actual value.
|
||||||
|
*
|
||||||
|
* @return The Filter object to be added to the servlet
|
||||||
|
*/
|
||||||
|
public Filter getFilter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the class of the Filter object that should be added to the servlet.
|
||||||
|
*
|
||||||
|
* This method is considered "mutually exclusive" from the getFilter method.
|
||||||
|
* That is, one of them should return null and the other should return an actual value.
|
||||||
|
*
|
||||||
|
* @return The class of the Filter object to be added to the servlet
|
||||||
|
*/
|
||||||
|
public Class<? extends Filter> getFilterClass();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Filter initialization parameters.
|
||||||
|
*
|
||||||
|
* @return a map containing all the Filter initialization
|
||||||
|
* parameters
|
||||||
|
*/
|
||||||
|
public Map<String,String> getInitParameters();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path that this Filter should apply to
|
||||||
|
*
|
||||||
|
* @return the path that this Filter should apply to
|
||||||
|
*/
|
||||||
|
public String getPath();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The dispatcher type that this Filter should apply to
|
||||||
|
*
|
||||||
|
* @return the enumeration of DispatcherTypes that this Filter should apply to
|
||||||
|
*/
|
||||||
|
public EnumSet<DispatcherType> getDispatcherType();
|
||||||
|
}
|
|
@ -38,9 +38,9 @@ import io.druid.guice.annotations.Smile;
|
||||||
import io.druid.guice.http.DruidHttpClientConfig;
|
import io.druid.guice.http.DruidHttpClientConfig;
|
||||||
import io.druid.initialization.Initialization;
|
import io.druid.initialization.Initialization;
|
||||||
import io.druid.query.Query;
|
import io.druid.query.Query;
|
||||||
import io.druid.server.initialization.BaseJettyServerInitializer;
|
|
||||||
import io.druid.server.initialization.JettyServerInitializer;
|
|
||||||
import io.druid.server.initialization.BaseJettyTest;
|
import io.druid.server.initialization.BaseJettyTest;
|
||||||
|
import io.druid.server.initialization.jetty.JettyServerInitUtils;
|
||||||
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
import io.druid.server.log.RequestLogger;
|
import io.druid.server.log.RequestLogger;
|
||||||
import io.druid.server.metrics.NoopServiceEmitter;
|
import io.druid.server.metrics.NoopServiceEmitter;
|
||||||
import io.druid.server.router.QueryHostFinder;
|
import io.druid.server.router.QueryHostFinder;
|
||||||
|
@ -122,7 +122,7 @@ public class AsyncQueryForwardingServletTest extends BaseJettyTest
|
||||||
Assert.assertNotEquals("gzip", postNoGzip.getContentEncoding());
|
Assert.assertNotEquals("gzip", postNoGzip.getContentEncoding());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ProxyJettyServerInit extends BaseJettyServerInitializer
|
public static class ProxyJettyServerInit implements JettyServerInitializer
|
||||||
{
|
{
|
||||||
|
|
||||||
private final DruidNode node;
|
private final DruidNode node;
|
||||||
|
@ -181,8 +181,8 @@ public class AsyncQueryForwardingServletTest extends BaseJettyTest
|
||||||
}
|
}
|
||||||
), "/proxy/*"
|
), "/proxy/*"
|
||||||
);
|
);
|
||||||
|
JettyServerInitUtils.addExtensionFilters(root, injector);
|
||||||
root.addFilter(defaultAsyncGzipFilterHolder(), "/*", null);
|
root.addFilter(JettyServerInitUtils.defaultAsyncGzipFilterHolder(), "/*", null);
|
||||||
root.addFilter(GuiceFilter.class, "/slow/*", null);
|
root.addFilter(GuiceFilter.class, "/slow/*", null);
|
||||||
root.addFilter(GuiceFilter.class, "/default/*", null);
|
root.addFilter(GuiceFilter.class, "/default/*", null);
|
||||||
root.addFilter(GuiceFilter.class, "/exception/*", null);
|
root.addFilter(GuiceFilter.class, "/exception/*", null);
|
||||||
|
|
|
@ -25,6 +25,7 @@ import com.google.inject.Binder;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Key;
|
import com.google.inject.Key;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
import com.google.inject.multibindings.Multibinder;
|
||||||
import com.google.inject.servlet.GuiceFilter;
|
import com.google.inject.servlet.GuiceFilter;
|
||||||
import com.metamx.common.lifecycle.Lifecycle;
|
import com.metamx.common.lifecycle.Lifecycle;
|
||||||
import com.metamx.http.client.HttpClient;
|
import com.metamx.http.client.HttpClient;
|
||||||
|
@ -38,6 +39,10 @@ import io.druid.guice.LifecycleModule;
|
||||||
import io.druid.guice.annotations.Self;
|
import io.druid.guice.annotations.Self;
|
||||||
import io.druid.initialization.Initialization;
|
import io.druid.initialization.Initialization;
|
||||||
import io.druid.server.DruidNode;
|
import io.druid.server.DruidNode;
|
||||||
|
import io.druid.server.initialization.jetty.JettyServerInitUtils;
|
||||||
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
|
import io.druid.server.initialization.jetty.ServletFilterHolder;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Handler;
|
import org.eclipse.jetty.server.Handler;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.handler.HandlerList;
|
import org.eclipse.jetty.server.handler.HandlerList;
|
||||||
|
@ -49,7 +54,15 @@ import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.servlet.DispatcherType;
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletOutputStream;
|
import javax.servlet.ServletOutputStream;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
|
@ -59,6 +72,8 @@ import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -101,6 +116,44 @@ public class BaseJettyTest
|
||||||
binder, Key.get(DruidNode.class, Self.class), new DruidNode("test", "localhost", null)
|
binder, Key.get(DruidNode.class, Self.class), new DruidNode("test", "localhost", null)
|
||||||
);
|
);
|
||||||
binder.bind(JettyServerInitializer.class).to(JettyServerInit.class).in(LazySingleton.class);
|
binder.bind(JettyServerInitializer.class).to(JettyServerInit.class).in(LazySingleton.class);
|
||||||
|
|
||||||
|
Multibinder<ServletFilterHolder> multibinder = Multibinder.newSetBinder(binder, ServletFilterHolder.class);
|
||||||
|
multibinder.addBinding().toInstance(
|
||||||
|
new ServletFilterHolder()
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPath()
|
||||||
|
{
|
||||||
|
return "/*";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getInitParameters()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends Filter> getFilterClass()
|
||||||
|
{
|
||||||
|
return DummyAuthFilter.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Filter getFilter()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<DispatcherType> getDispatcherType()
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Jerseys.addResource(binder, SlowResource.class);
|
Jerseys.addResource(binder, SlowResource.class);
|
||||||
Jerseys.addResource(binder, ExceptionResource.class);
|
Jerseys.addResource(binder, ExceptionResource.class);
|
||||||
Jerseys.addResource(binder, DefaultResource.class);
|
Jerseys.addResource(binder, DefaultResource.class);
|
||||||
|
@ -140,7 +193,7 @@ public class BaseJettyTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class JettyServerInit extends BaseJettyServerInitializer
|
public static class JettyServerInit implements JettyServerInitializer
|
||||||
{
|
{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -148,7 +201,8 @@ public class BaseJettyTest
|
||||||
{
|
{
|
||||||
final ServletContextHandler root = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
final ServletContextHandler root = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||||
root.addServlet(new ServletHolder(new DefaultServlet()), "/*");
|
root.addServlet(new ServletHolder(new DefaultServlet()), "/*");
|
||||||
root.addFilter(defaultGzipFilterHolder(), "/*", null);
|
JettyServerInitUtils.addExtensionFilters(root, injector);
|
||||||
|
root.addFilter(JettyServerInitUtils.defaultGzipFilterHolder(), "/*", null);
|
||||||
root.addFilter(GuiceFilter.class, "/*", null);
|
root.addFilter(GuiceFilter.class, "/*", null);
|
||||||
|
|
||||||
final HandlerList handlerList = new HandlerList();
|
final HandlerList handlerList = new HandlerList();
|
||||||
|
@ -219,4 +273,33 @@ public class BaseJettyTest
|
||||||
throw new IOException();
|
throw new IOException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class DummyAuthFilter implements Filter {
|
||||||
|
|
||||||
|
public static final String AUTH_HDR = "secretUser";
|
||||||
|
public static final String SECRET_USER = "bob";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) throws ServletException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException,
|
||||||
|
ServletException
|
||||||
|
{
|
||||||
|
HttpServletRequest request = (HttpServletRequest) req;
|
||||||
|
if(request.getHeader(AUTH_HDR) == null || request.getHeader(AUTH_HDR).equals(SECRET_USER)) {
|
||||||
|
chain.doFilter(req, resp);
|
||||||
|
} else {
|
||||||
|
HttpServletResponse response = (HttpServletResponse) resp;
|
||||||
|
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Failed even fake authentication.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,8 @@ import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
public class JettyTest extends BaseJettyTest
|
public class JettyTest extends BaseJettyTest
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -179,4 +181,17 @@ public class JettyTest extends BaseJettyTest
|
||||||
|
|
||||||
latch.await(5, TimeUnit.SECONDS);
|
latch.await(5, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExtensionAuthFilter() throws Exception
|
||||||
|
{
|
||||||
|
URL url = new URL("http://localhost:" + port + "/default");
|
||||||
|
HttpURLConnection get = (HttpURLConnection) url.openConnection();
|
||||||
|
get.setRequestProperty(DummyAuthFilter.AUTH_HDR, DummyAuthFilter.SECRET_USER);
|
||||||
|
Assert.assertEquals(HttpServletResponse.SC_OK, get.getResponseCode());
|
||||||
|
|
||||||
|
get = (HttpURLConnection) url.openConnection();
|
||||||
|
get.setRequestProperty(DummyAuthFilter.AUTH_HDR, "hacker");
|
||||||
|
Assert.assertEquals(HttpServletResponse.SC_UNAUTHORIZED, get.getResponseCode());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,8 +54,9 @@ import io.druid.server.coordination.AbstractDataSegmentAnnouncer;
|
||||||
import io.druid.server.coordination.BatchDataSegmentAnnouncer;
|
import io.druid.server.coordination.BatchDataSegmentAnnouncer;
|
||||||
import io.druid.server.coordination.DruidServerMetadata;
|
import io.druid.server.coordination.DruidServerMetadata;
|
||||||
import io.druid.server.initialization.BatchDataSegmentAnnouncerConfig;
|
import io.druid.server.initialization.BatchDataSegmentAnnouncerConfig;
|
||||||
import io.druid.server.initialization.JettyServerInitializer;
|
|
||||||
import io.druid.server.initialization.ZkPathsConfig;
|
import io.druid.server.initialization.ZkPathsConfig;
|
||||||
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
|
|
||||||
import org.apache.curator.framework.CuratorFramework;
|
import org.apache.curator.framework.CuratorFramework;
|
||||||
import org.apache.curator.framework.CuratorFrameworkFactory;
|
import org.apache.curator.framework.CuratorFrameworkFactory;
|
||||||
import org.apache.curator.retry.BoundedExponentialBackoffRetry;
|
import org.apache.curator.retry.BoundedExponentialBackoffRetry;
|
||||||
|
|
|
@ -47,7 +47,7 @@ import io.druid.server.ClientQuerySegmentWalker;
|
||||||
import io.druid.server.QueryResource;
|
import io.druid.server.QueryResource;
|
||||||
import io.druid.server.coordination.broker.DruidBroker;
|
import io.druid.server.coordination.broker.DruidBroker;
|
||||||
import io.druid.server.http.BrokerResource;
|
import io.druid.server.http.BrokerResource;
|
||||||
import io.druid.server.initialization.JettyServerInitializer;
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
import io.druid.server.metrics.MetricsModule;
|
import io.druid.server.metrics.MetricsModule;
|
||||||
import io.druid.server.router.TieredBrokerConfig;
|
import io.druid.server.router.TieredBrokerConfig;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
|
|
|
@ -54,7 +54,7 @@ import io.druid.server.http.RedirectInfo;
|
||||||
import io.druid.server.http.RulesResource;
|
import io.druid.server.http.RulesResource;
|
||||||
import io.druid.server.http.ServersResource;
|
import io.druid.server.http.ServersResource;
|
||||||
import io.druid.server.http.TiersResource;
|
import io.druid.server.http.TiersResource;
|
||||||
import io.druid.server.initialization.JettyServerInitializer;
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
import io.druid.server.router.TieredBrokerConfig;
|
import io.druid.server.router.TieredBrokerConfig;
|
||||||
import org.apache.curator.framework.CuratorFramework;
|
import org.apache.curator.framework.CuratorFramework;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
|
|
|
@ -38,7 +38,7 @@ import io.druid.server.QueryResource;
|
||||||
import io.druid.server.coordination.ServerManager;
|
import io.druid.server.coordination.ServerManager;
|
||||||
import io.druid.server.coordination.ZkCoordinator;
|
import io.druid.server.coordination.ZkCoordinator;
|
||||||
import io.druid.server.http.HistoricalResource;
|
import io.druid.server.http.HistoricalResource;
|
||||||
import io.druid.server.initialization.JettyServerInitializer;
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
import io.druid.server.metrics.MetricsModule;
|
import io.druid.server.metrics.MetricsModule;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,8 @@ import io.druid.indexing.worker.config.WorkerConfig;
|
||||||
import io.druid.indexing.worker.http.WorkerResource;
|
import io.druid.indexing.worker.http.WorkerResource;
|
||||||
import io.druid.segment.realtime.firehose.ChatHandlerProvider;
|
import io.druid.segment.realtime.firehose.ChatHandlerProvider;
|
||||||
import io.druid.server.DruidNode;
|
import io.druid.server.DruidNode;
|
||||||
import io.druid.server.initialization.JettyServerInitializer;
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
@ -71,8 +71,8 @@ import io.druid.indexing.worker.config.WorkerConfig;
|
||||||
import io.druid.segment.realtime.firehose.ChatHandlerProvider;
|
import io.druid.segment.realtime.firehose.ChatHandlerProvider;
|
||||||
import io.druid.server.http.RedirectFilter;
|
import io.druid.server.http.RedirectFilter;
|
||||||
import io.druid.server.http.RedirectInfo;
|
import io.druid.server.http.RedirectInfo;
|
||||||
import io.druid.server.initialization.BaseJettyServerInitializer;
|
import io.druid.server.initialization.jetty.JettyServerInitUtils;
|
||||||
import io.druid.server.initialization.JettyServerInitializer;
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
import io.druid.tasklogs.TaskLogStreamer;
|
import io.druid.tasklogs.TaskLogStreamer;
|
||||||
import io.druid.tasklogs.TaskLogs;
|
import io.druid.tasklogs.TaskLogs;
|
||||||
import org.eclipse.jetty.server.Handler;
|
import org.eclipse.jetty.server.Handler;
|
||||||
|
@ -217,7 +217,7 @@ public class CliOverlord extends ServerRunnable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
private static class OverlordJettyServerInitializer extends BaseJettyServerInitializer
|
private static class OverlordJettyServerInitializer implements JettyServerInitializer
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void initialize(Server server, Injector injector)
|
public void initialize(Server server, Injector injector)
|
||||||
|
@ -235,7 +235,8 @@ public class CliOverlord extends ServerRunnable
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
root.addFilter(defaultGzipFilterHolder(), "/*", null);
|
JettyServerInitUtils.addExtensionFilters(root, injector);
|
||||||
|
root.addFilter(JettyServerInitUtils.defaultGzipFilterHolder(), "/*", null);
|
||||||
|
|
||||||
// /status should not redirect, so add first
|
// /status should not redirect, so add first
|
||||||
root.addFilter(GuiceFilter.class, "/status/*", null);
|
root.addFilter(GuiceFilter.class, "/status/*", null);
|
||||||
|
|
|
@ -69,7 +69,8 @@ import io.druid.segment.realtime.firehose.ChatHandlerResource;
|
||||||
import io.druid.segment.realtime.firehose.NoopChatHandlerProvider;
|
import io.druid.segment.realtime.firehose.NoopChatHandlerProvider;
|
||||||
import io.druid.segment.realtime.firehose.ServiceAnnouncingChatHandlerProvider;
|
import io.druid.segment.realtime.firehose.ServiceAnnouncingChatHandlerProvider;
|
||||||
import io.druid.server.QueryResource;
|
import io.druid.server.QueryResource;
|
||||||
import io.druid.server.initialization.JettyServerInitializer;
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
|
@ -34,7 +34,7 @@ import io.druid.guice.LifecycleModule;
|
||||||
import io.druid.guice.ManageLifecycle;
|
import io.druid.guice.ManageLifecycle;
|
||||||
import io.druid.guice.annotations.Self;
|
import io.druid.guice.annotations.Self;
|
||||||
import io.druid.guice.http.JettyHttpClientModule;
|
import io.druid.guice.http.JettyHttpClientModule;
|
||||||
import io.druid.server.initialization.JettyServerInitializer;
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
import io.druid.server.router.CoordinatorRuleManager;
|
import io.druid.server.router.CoordinatorRuleManager;
|
||||||
import io.druid.server.router.QueryHostFinder;
|
import io.druid.server.router.QueryHostFinder;
|
||||||
import io.druid.server.router.Router;
|
import io.druid.server.router.Router;
|
||||||
|
|
|
@ -22,7 +22,9 @@ import com.google.inject.Injector;
|
||||||
import com.google.inject.servlet.GuiceFilter;
|
import com.google.inject.servlet.GuiceFilter;
|
||||||
import io.druid.server.coordinator.DruidCoordinatorConfig;
|
import io.druid.server.coordinator.DruidCoordinatorConfig;
|
||||||
import io.druid.server.http.RedirectFilter;
|
import io.druid.server.http.RedirectFilter;
|
||||||
import io.druid.server.initialization.BaseJettyServerInitializer;
|
import io.druid.server.initialization.jetty.JettyServerInitUtils;
|
||||||
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Handler;
|
import org.eclipse.jetty.server.Handler;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.handler.HandlerList;
|
import org.eclipse.jetty.server.handler.HandlerList;
|
||||||
|
@ -34,7 +36,7 @@ import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
class CoordinatorJettyServerInitializer extends BaseJettyServerInitializer
|
class CoordinatorJettyServerInitializer implements JettyServerInitializer
|
||||||
{
|
{
|
||||||
private final DruidCoordinatorConfig config;
|
private final DruidCoordinatorConfig config;
|
||||||
|
|
||||||
|
@ -57,7 +59,8 @@ class CoordinatorJettyServerInitializer extends BaseJettyServerInitializer
|
||||||
} else {
|
} else {
|
||||||
root.setResourceBase(config.getConsoleStatic());
|
root.setResourceBase(config.getConsoleStatic());
|
||||||
}
|
}
|
||||||
root.addFilter(defaultGzipFilterHolder(), "/*", null);
|
JettyServerInitUtils.addExtensionFilters(root, injector);
|
||||||
|
root.addFilter(JettyServerInitUtils.defaultGzipFilterHolder(), "/*", null);
|
||||||
|
|
||||||
// /status should not redirect, so add first
|
// /status should not redirect, so add first
|
||||||
root.addFilter(GuiceFilter.class, "/status/*", null);
|
root.addFilter(GuiceFilter.class, "/status/*", null);
|
||||||
|
|
|
@ -17,9 +17,11 @@
|
||||||
|
|
||||||
package io.druid.cli;
|
package io.druid.cli;
|
||||||
|
|
||||||
|
import io.druid.server.initialization.jetty.JettyServerInitUtils;
|
||||||
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
|
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.servlet.GuiceFilter;
|
import com.google.inject.servlet.GuiceFilter;
|
||||||
import io.druid.server.initialization.BaseJettyServerInitializer;
|
|
||||||
import org.eclipse.jetty.server.Handler;
|
import org.eclipse.jetty.server.Handler;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.handler.DefaultHandler;
|
import org.eclipse.jetty.server.handler.DefaultHandler;
|
||||||
|
@ -30,14 +32,15 @@ import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
class MiddleManagerJettyServerInitializer extends BaseJettyServerInitializer
|
class MiddleManagerJettyServerInitializer implements JettyServerInitializer
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void initialize(Server server, Injector injector)
|
public void initialize(Server server, Injector injector)
|
||||||
{
|
{
|
||||||
final ServletContextHandler root = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
final ServletContextHandler root = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||||
root.addServlet(new ServletHolder(new DefaultServlet()), "/*");
|
root.addServlet(new ServletHolder(new DefaultServlet()), "/*");
|
||||||
root.addFilter(defaultGzipFilterHolder(), "/*", null);
|
JettyServerInitUtils.addExtensionFilters(root, injector);
|
||||||
|
root.addFilter(JettyServerInitUtils.defaultGzipFilterHolder(), "/*", null);
|
||||||
root.addFilter(GuiceFilter.class, "/*", null);
|
root.addFilter(GuiceFilter.class, "/*", null);
|
||||||
|
|
||||||
final HandlerList handlerList = new HandlerList();
|
final HandlerList handlerList = new HandlerList();
|
||||||
|
|
|
@ -19,7 +19,10 @@ package io.druid.cli;
|
||||||
|
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.servlet.GuiceFilter;
|
import com.google.inject.servlet.GuiceFilter;
|
||||||
import io.druid.server.initialization.BaseJettyServerInitializer;
|
|
||||||
|
import io.druid.server.initialization.jetty.JettyServerInitUtils;
|
||||||
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Handler;
|
import org.eclipse.jetty.server.Handler;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.handler.HandlerList;
|
import org.eclipse.jetty.server.handler.HandlerList;
|
||||||
|
@ -29,14 +32,15 @@ import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class QueryJettyServerInitializer extends BaseJettyServerInitializer
|
public class QueryJettyServerInitializer implements JettyServerInitializer
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void initialize(Server server, Injector injector)
|
public void initialize(Server server, Injector injector)
|
||||||
{
|
{
|
||||||
final ServletContextHandler root = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
final ServletContextHandler root = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||||
root.addServlet(new ServletHolder(new DefaultServlet()), "/*");
|
root.addServlet(new ServletHolder(new DefaultServlet()), "/*");
|
||||||
root.addFilter(defaultGzipFilterHolder(), "/*", null);
|
JettyServerInitUtils.addExtensionFilters(root, injector);
|
||||||
|
root.addFilter(JettyServerInitUtils.defaultGzipFilterHolder(), "/*", null);
|
||||||
|
|
||||||
root.addFilter(GuiceFilter.class, "/*", null);
|
root.addFilter(GuiceFilter.class, "/*", null);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,8 @@ import io.druid.guice.annotations.Json;
|
||||||
import io.druid.guice.annotations.Smile;
|
import io.druid.guice.annotations.Smile;
|
||||||
import io.druid.guice.http.DruidHttpClientConfig;
|
import io.druid.guice.http.DruidHttpClientConfig;
|
||||||
import io.druid.server.AsyncQueryForwardingServlet;
|
import io.druid.server.AsyncQueryForwardingServlet;
|
||||||
import io.druid.server.initialization.BaseJettyServerInitializer;
|
import io.druid.server.initialization.jetty.JettyServerInitUtils;
|
||||||
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
import io.druid.server.log.RequestLogger;
|
import io.druid.server.log.RequestLogger;
|
||||||
import io.druid.server.router.QueryHostFinder;
|
import io.druid.server.router.QueryHostFinder;
|
||||||
import io.druid.server.router.Router;
|
import io.druid.server.router.Router;
|
||||||
|
@ -41,7 +42,7 @@ import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class RouterJettyServerInitializer extends BaseJettyServerInitializer
|
public class RouterJettyServerInitializer implements JettyServerInitializer
|
||||||
{
|
{
|
||||||
private final ObjectMapper jsonMapper;
|
private final ObjectMapper jsonMapper;
|
||||||
private final ObjectMapper smileMapper;
|
private final ObjectMapper smileMapper;
|
||||||
|
@ -88,9 +89,9 @@ public class RouterJettyServerInitializer extends BaseJettyServerInitializer
|
||||||
requestLogger
|
requestLogger
|
||||||
);
|
);
|
||||||
asyncQueryForwardingServlet.setTimeout(httpClientConfig.getReadTimeout().getMillis());
|
asyncQueryForwardingServlet.setTimeout(httpClientConfig.getReadTimeout().getMillis());
|
||||||
|
|
||||||
root.addServlet(new ServletHolder(asyncQueryForwardingServlet), "/druid/v2/*");
|
root.addServlet(new ServletHolder(asyncQueryForwardingServlet), "/druid/v2/*");
|
||||||
root.addFilter(defaultAsyncGzipFilterHolder(), "/*", null);
|
JettyServerInitUtils.addExtensionFilters(root, injector);
|
||||||
|
root.addFilter(JettyServerInitUtils.defaultAsyncGzipFilterHolder(), "/*", null);
|
||||||
// Can't use '/*' here because of Guice conflicts with AsyncQueryForwardingServlet path
|
// Can't use '/*' here because of Guice conflicts with AsyncQueryForwardingServlet path
|
||||||
root.addFilter(GuiceFilter.class, "/status/*", null);
|
root.addFilter(GuiceFilter.class, "/status/*", null);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,8 @@ import io.druid.segment.realtime.firehose.ChatHandlerResource;
|
||||||
import io.druid.segment.realtime.firehose.NoopChatHandlerProvider;
|
import io.druid.segment.realtime.firehose.NoopChatHandlerProvider;
|
||||||
import io.druid.segment.realtime.firehose.ServiceAnnouncingChatHandlerProvider;
|
import io.druid.segment.realtime.firehose.ServiceAnnouncingChatHandlerProvider;
|
||||||
import io.druid.server.QueryResource;
|
import io.druid.server.QueryResource;
|
||||||
import io.druid.server.initialization.JettyServerInitializer;
|
import io.druid.server.initialization.jetty.JettyServerInitializer;
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
Loading…
Reference in New Issue