From 0064a55ac5343b53a72e76e7ea604bf3160bd6a8 Mon Sep 17 00:00:00 2001 From: Mikko Karjalainen Date: Tue, 13 Nov 2018 15:44:10 +0000 Subject: [PATCH] Add a feature flag to enable/disable request tracking feature. --- .../com/hotels/styx/ServerConfigSchema.java | 3 ++- .../proxy/InterceptorPipelineBuilder.java | 6 +++-- .../styx/proxy/ProxyConnectorFactory.java | 21 ++++++++++----- .../hotels/styx/proxy/ProxyServerBuilder.java | 3 ++- .../styx/routing/StaticPipelineFactory.java | 17 +++++++++--- .../handlers/HttpInterceptorPipeline.java | 16 +++++++++--- .../handlers/StandardHttpPipeline.java | 22 +++++++++------- .../styx/startup/StyxPipelineFactory.java | 22 ++++++++++------ .../java/com/hotels/styx/StyxConfigTest.java | 2 -- .../proxy/InterceptorPipelineBuilderTest.java | 2 +- .../com/hotels/styx/proxy/StyxProxyTest.java | 2 +- .../routing/StaticPipelineBuilderTest.java | 4 +-- .../handlers/StandardHttpPipelineTest.java | 26 +++---------------- .../netty/connectors/HttpPipelineHandler.java | 6 ++--- docs/user-guide/admin-interface.md | 4 ++- docs/user-guide/configure-overview.md | 6 +++++ 16 files changed, 92 insertions(+), 70 deletions(-) diff --git a/components/proxy/src/main/java/com/hotels/styx/ServerConfigSchema.java b/components/proxy/src/main/java/com/hotels/styx/ServerConfigSchema.java index e17f23a4ff..04240a1423 100644 --- a/components/proxy/src/main/java/com/hotels/styx/ServerConfigSchema.java +++ b/components/proxy/src/main/java/com/hotels/styx/ServerConfigSchema.java @@ -145,7 +145,8 @@ final class ServerConfigSchema { optional("responseInfoHeaderFormat", string()), optional("httpPipeline", object(opaque())), optional("logFormat", string()), - optional("userDefined", object(opaque())) + optional("userDefined", object(opaque())), + optional("requestTracking", bool()) )) .build(); diff --git a/components/proxy/src/main/java/com/hotels/styx/proxy/InterceptorPipelineBuilder.java b/components/proxy/src/main/java/com/hotels/styx/proxy/InterceptorPipelineBuilder.java index 6a2b0da168..1c06b237a2 100644 --- a/components/proxy/src/main/java/com/hotels/styx/proxy/InterceptorPipelineBuilder.java +++ b/components/proxy/src/main/java/com/hotels/styx/proxy/InterceptorPipelineBuilder.java @@ -36,16 +36,18 @@ public class InterceptorPipelineBuilder { private final Environment environment; private final Iterable plugins; private final HttpHandler handler; + private final boolean trackRequests; - public InterceptorPipelineBuilder(Environment environment, Iterable plugins, HttpHandler handler) { + public InterceptorPipelineBuilder(Environment environment, Iterable plugins, HttpHandler handler, boolean trackRequests) { this.environment = requireNonNull(environment); this.plugins = requireNonNull(plugins); this.handler = requireNonNull(handler); + this.trackRequests = trackRequests; } public HttpHandler build() { List interceptors = ImmutableList.copyOf(instrument(plugins, environment)); - return new HttpInterceptorPipeline(interceptors, handler); + return new HttpInterceptorPipeline(interceptors, handler, trackRequests); } private static List instrument(Iterable namedPlugins, Environment environment) { diff --git a/components/proxy/src/main/java/com/hotels/styx/proxy/ProxyConnectorFactory.java b/components/proxy/src/main/java/com/hotels/styx/proxy/ProxyConnectorFactory.java index bb08387948..0e7114b237 100644 --- a/components/proxy/src/main/java/com/hotels/styx/proxy/ProxyConnectorFactory.java +++ b/components/proxy/src/main/java/com/hotels/styx/proxy/ProxyConnectorFactory.java @@ -16,13 +16,13 @@ package com.hotels.styx.proxy; import com.codahale.metrics.Histogram; -import com.hotels.styx.server.HttpErrorStatusListener; import com.hotels.styx.api.HttpHandler; import com.hotels.styx.api.MetricRegistry; -import com.hotels.styx.server.RequestStatsCollector; import com.hotels.styx.proxy.encoders.ConfigurableUnwiseCharsEncoder; import com.hotels.styx.server.HttpConnectorConfig; +import com.hotels.styx.server.HttpErrorStatusListener; import com.hotels.styx.server.HttpsConnectorConfig; +import com.hotels.styx.server.RequestStatsCollector; import com.hotels.styx.server.netty.NettyServerConfig; import com.hotels.styx.server.netty.ServerConnector; import com.hotels.styx.server.netty.ServerConnectorFactory; @@ -33,6 +33,7 @@ import com.hotels.styx.server.netty.handlers.ExcessConnectionRejector; import com.hotels.styx.server.netty.handlers.RequestTimeoutHandler; import com.hotels.styx.server.track.CurrentRequestTracker; +import com.hotels.styx.server.track.RequestTracker; import io.netty.channel.Channel; import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelHandlerContext; @@ -64,27 +65,30 @@ class ProxyConnectorFactory implements ServerConnectorFactory { private final NettyServerConfig serverConfig; private final String unwiseCharacters; private final ResponseEnhancer responseEnhancer; + private final boolean requestTracking; ProxyConnectorFactory(NettyServerConfig serverConfig, MetricRegistry metrics, HttpErrorStatusListener errorStatusListener, String unwiseCharacters, - ResponseEnhancer responseEnhancer) { + ResponseEnhancer responseEnhancer, + boolean requestTracking) { this.serverConfig = requireNonNull(serverConfig); this.metrics = requireNonNull(metrics); this.errorStatusListener = requireNonNull(errorStatusListener); this.unwiseCharacters = requireNonNull(unwiseCharacters); this.responseEnhancer = requireNonNull(responseEnhancer); + this.requestTracking = requestTracking; } @Override public ServerConnector create(HttpConnectorConfig config) { - return new ProxyConnector(config, serverConfig, metrics, errorStatusListener, unwiseCharacters, responseEnhancer); + return new ProxyConnector(config, serverConfig, metrics, errorStatusListener, unwiseCharacters, responseEnhancer, requestTracking); } @Override public ServerConnector create(HttpsConnectorConfig config) { - return new ProxyConnector(config, serverConfig, metrics, errorStatusListener, unwiseCharacters, responseEnhancer); + return new ProxyConnector(config, serverConfig, metrics, errorStatusListener, unwiseCharacters, responseEnhancer, requestTracking); } private static final class ProxyConnector implements ServerConnector { @@ -98,13 +102,15 @@ private static final class ProxyConnector implements ServerConnector { private final ConfigurableUnwiseCharsEncoder unwiseCharEncoder; private final Optional sslContext; private final ResponseEnhancer responseEnhancer; + private final RequestTracker requestTracker; private ProxyConnector(HttpConnectorConfig config, NettyServerConfig serverConfig, MetricRegistry metrics, HttpErrorStatusListener errorStatusListener, String unwiseCharacters, - ResponseEnhancer responseEnhancer) { + ResponseEnhancer responseEnhancer, + boolean requestTracking) { this.responseEnhancer = requireNonNull(responseEnhancer); this.config = requireNonNull(config); this.serverConfig = requireNonNull(serverConfig); @@ -119,6 +125,7 @@ private ProxyConnector(HttpConnectorConfig config, } else { this.sslContext = Optional.empty(); } + this.requestTracker = requestTracking ? CurrentRequestTracker.INSTANCE : RequestTracker.NO_OP; } @Override @@ -162,7 +169,7 @@ public void configure(Channel channel, HttpHandler httpPipeline) { .progressListener(requestStatsCollector) .metricRegistry(metrics) .secure(sslContext.isPresent()) - .requestTracker(CurrentRequestTracker.INSTANCE) + .requestTracker(requestTracker) .build()); } diff --git a/components/proxy/src/main/java/com/hotels/styx/proxy/ProxyServerBuilder.java b/components/proxy/src/main/java/com/hotels/styx/proxy/ProxyServerBuilder.java index 934f45c275..de14822041 100644 --- a/components/proxy/src/main/java/com/hotels/styx/proxy/ProxyServerBuilder.java +++ b/components/proxy/src/main/java/com/hotels/styx/proxy/ProxyServerBuilder.java @@ -46,9 +46,10 @@ public ProxyServerBuilder(Environment environment) { public HttpServer build() { ProxyServerConfig proxyConfig = environment.styxConfig().proxyServerConfig(); String unwiseCharacters = environment.styxConfig().get(ENCODE_UNWISECHARS).orElse(""); + boolean requestTracking = environment.configuration().get("requestTracking", Boolean.class).orElse(false); return new NettyServerBuilderSpec("Proxy", environment.serverEnvironment(), - new ProxyConnectorFactory(proxyConfig, environment.metricRegistry(), environment.errorListener(), unwiseCharacters, this::addInfoHeader)) + new ProxyConnectorFactory(proxyConfig, environment.metricRegistry(), environment.errorListener(), unwiseCharacters, this::addInfoHeader, requestTracking)) .toNettyServerBuilder(proxyConfig) .httpHandler(httpHandler) // register health check diff --git a/components/proxy/src/main/java/com/hotels/styx/routing/StaticPipelineFactory.java b/components/proxy/src/main/java/com/hotels/styx/routing/StaticPipelineFactory.java index ec22e82e54..c4f62a0729 100644 --- a/components/proxy/src/main/java/com/hotels/styx/routing/StaticPipelineFactory.java +++ b/components/proxy/src/main/java/com/hotels/styx/routing/StaticPipelineFactory.java @@ -36,17 +36,26 @@ public class StaticPipelineFactory implements HttpPipelineFactory { private final Environment environment; private final Registry registry; private final Iterable plugins; + private final boolean trackRequests; @VisibleForTesting - StaticPipelineFactory(BackendServiceClientFactory clientFactory, Environment environment, Registry registry, Iterable plugins) { + StaticPipelineFactory(BackendServiceClientFactory clientFactory, + Environment environment, + Registry registry, + Iterable plugins, + boolean trackRequests) { this.clientFactory = clientFactory; this.environment = environment; this.registry = registry; this.plugins = plugins; + this.trackRequests = trackRequests; } - public StaticPipelineFactory(Environment environment, Registry registry, Iterable plugins) { - this(createClientFactory(environment), environment, registry, plugins); + public StaticPipelineFactory(Environment environment, + Registry registry, + Iterable plugins, + boolean trackRequests) { + this(createClientFactory(environment), environment, registry, plugins, trackRequests); } private static BackendServiceClientFactory createClientFactory(Environment environment) { @@ -59,6 +68,6 @@ public HttpHandler build() { registry.addListener(backendServicesRouter); RouteHandlerAdapter router = new RouteHandlerAdapter(backendServicesRouter); - return new InterceptorPipelineBuilder(environment, plugins, router).build(); + return new InterceptorPipelineBuilder(environment, plugins, router, trackRequests).build(); } } diff --git a/components/proxy/src/main/java/com/hotels/styx/routing/handlers/HttpInterceptorPipeline.java b/components/proxy/src/main/java/com/hotels/styx/routing/handlers/HttpInterceptorPipeline.java index db4cc39740..fb7756e4c6 100644 --- a/components/proxy/src/main/java/com/hotels/styx/routing/handlers/HttpInterceptorPipeline.java +++ b/components/proxy/src/main/java/com/hotels/styx/routing/handlers/HttpInterceptorPipeline.java @@ -31,6 +31,8 @@ import com.hotels.styx.routing.config.RouteHandlerDefinition; import com.hotels.styx.routing.config.RouteHandlerFactory; import com.hotels.styx.routing.config.RouteHandlerReference; +import com.hotels.styx.server.track.CurrentRequestTracker; +import com.hotels.styx.server.track.RequestTracker; import java.util.List; import java.util.Map; @@ -50,8 +52,9 @@ public class HttpInterceptorPipeline implements HttpHandler { private final StandardHttpPipeline handler; - public HttpInterceptorPipeline(List interceptors, HttpHandler handler) { - this.handler = new StandardHttpPipeline(interceptors, handler); + public HttpInterceptorPipeline(List interceptors, HttpHandler handler, boolean trackRequests) { + RequestTracker tracker = trackRequests ? CurrentRequestTracker.INSTANCE : RequestTracker.NO_OP; + this.handler = new StandardHttpPipeline(interceptors, handler, tracker); } @Override @@ -65,10 +68,12 @@ public Eventual handle(LiveHttpRequest request, HttpIntercepto public static class ConfigFactory implements HttpHandlerFactory { private final Map interceptors; private final BuiltinInterceptorsFactory interceptorFactory; + private final boolean requestTracking; - public ConfigFactory(Iterable interceptors, BuiltinInterceptorsFactory interceptorFactory) { + public ConfigFactory(Iterable interceptors, BuiltinInterceptorsFactory interceptorFactory, boolean requestTracking) { this.interceptors = toMap(interceptors); this.interceptorFactory = interceptorFactory; + this.requestTracking = requestTracking; } private static List styxHttpPipeline(JsonNode pipeline) { @@ -100,7 +105,10 @@ public HttpHandler build(List parents, RouteHandlerFactory builtinsFacto .get("handler", RouteHandlerDefinition.class) .orElseThrow(() -> missingAttributeError(configBlock, join(".", parents), "handler")); - return new HttpInterceptorPipeline(interceptors, builtinsFactory.build(append(parents, "handler"), handlerConfig)); + return new HttpInterceptorPipeline( + interceptors, + builtinsFactory.build(append(parents, "handler"), handlerConfig), + requestTracking); } private List getHttpInterceptors(List parents, JsonNode pipeline) { diff --git a/components/proxy/src/main/java/com/hotels/styx/routing/handlers/StandardHttpPipeline.java b/components/proxy/src/main/java/com/hotels/styx/routing/handlers/StandardHttpPipeline.java index 73fd905693..022503391d 100644 --- a/components/proxy/src/main/java/com/hotels/styx/routing/handlers/StandardHttpPipeline.java +++ b/components/proxy/src/main/java/com/hotels/styx/routing/handlers/StandardHttpPipeline.java @@ -29,8 +29,8 @@ import com.hotels.styx.api.HttpInterceptor; import com.hotels.styx.api.LiveHttpRequest; import com.hotels.styx.api.LiveHttpResponse; -import com.hotels.styx.server.track.CurrentRequestTracker; +import com.hotels.styx.server.track.RequestTracker; import rx.Observable; /** @@ -39,19 +39,21 @@ class StandardHttpPipeline implements HttpHandler { private final List interceptors; private final HttpHandler handler; + private final RequestTracker requestTracker; public StandardHttpPipeline(HttpHandler handler) { - this(emptyList(), handler); + this(emptyList(), handler, RequestTracker.NO_OP); } - public StandardHttpPipeline(List interceptors, HttpHandler handler) { + public StandardHttpPipeline(List interceptors, HttpHandler handler, RequestTracker requestTracker) { this.interceptors = requireNonNull(interceptors); this.handler = requireNonNull(handler); + this.requestTracker = requireNonNull(requestTracker); } @Override public Eventual handle(LiveHttpRequest request, HttpInterceptor.Context context) { - HttpInterceptorChain interceptorsChain = new HttpInterceptorChain(interceptors, 0, handler, context); + HttpInterceptorChain interceptorsChain = new HttpInterceptorChain(interceptors, 0, handler, context, requestTracker); return interceptorsChain.proceed(request); } @@ -61,16 +63,18 @@ static final class HttpInterceptorChain implements HttpInterceptor.Chain { private final int index; private final HttpHandler client; private final HttpInterceptor.Context context; + private final RequestTracker requestTracker; - HttpInterceptorChain(List interceptors, int index, HttpHandler client, HttpInterceptor.Context context) { + HttpInterceptorChain(List interceptors, int index, HttpHandler client, HttpInterceptor.Context context, RequestTracker requestTracker) { this.interceptors = interceptors; this.index = index; this.client = client; this.context = context; + this.requestTracker = requireNonNull(requestTracker); } HttpInterceptorChain(HttpInterceptorChain adapter, int index) { - this(adapter.interceptors, index, adapter.client, adapter.context); + this(adapter.interceptors, index, adapter.client, adapter.context, adapter.requestTracker); } @Override @@ -80,7 +84,7 @@ public HttpInterceptor.Context context() { @Override public Eventual proceed(LiveHttpRequest request) { - CurrentRequestTracker.INSTANCE.trackRequest(request); + requestTracker.trackRequest(request); if (index < interceptors.size()) { HttpInterceptor.Chain chain = new HttpInterceptorChain(this, index + 1); @@ -93,7 +97,7 @@ public Eventual proceed(LiveHttpRequest request) { } } - CurrentRequestTracker.INSTANCE.markRequestAsSent(request); + requestTracker.markRequestAsSent(request); return new Eventual<>(toPublisher(toObservable(client.handle(request, this.context)) .compose(StandardHttpPipeline::sendErrorOnDoubleSubscription))); @@ -112,4 +116,4 @@ private static Observable sendErrorOnDoubleSubscription(Observ }); } -} \ No newline at end of file +} diff --git a/components/proxy/src/main/java/com/hotels/styx/startup/StyxPipelineFactory.java b/components/proxy/src/main/java/com/hotels/styx/startup/StyxPipelineFactory.java index 1e4880e7b1..cfee28b377 100644 --- a/components/proxy/src/main/java/com/hotels/styx/startup/StyxPipelineFactory.java +++ b/components/proxy/src/main/java/com/hotels/styx/startup/StyxPipelineFactory.java @@ -64,20 +64,24 @@ public HttpHandler create(StyxServerComponents config) { BuiltinInterceptorsFactory builtinInterceptorsFactory = new BuiltinInterceptorsFactory( ImmutableMap.of("Rewrite", new RewriteInterceptor.ConfigFactory())); + boolean requestTracking = config.environment().configuration().get("requestTracking", Boolean.class).orElse(false); + Map objectFactories = createBuiltinRoutingObjectFactories( config.environment(), config.services(), config.plugins(), - builtinInterceptorsFactory); + builtinInterceptorsFactory, + requestTracking); RouteHandlerFactory routeHandlerFactory = new RouteHandlerFactory(objectFactories, new ConcurrentHashMap<>()); return styxHttpPipeline( config.environment().styxConfig(), - configuredPipeline(config.environment(), config.services(), config.plugins(), routeHandlerFactory)); + configuredPipeline(config.environment(), config.services(), config.plugins(), routeHandlerFactory), + requestTracking); } - private static HttpHandler styxHttpPipeline(StyxConfig config, HttpHandler interceptorsPipeline) { + private static HttpHandler styxHttpPipeline(StyxConfig config, HttpHandler interceptorsPipeline, boolean requestTracking) { ImmutableList.Builder builder = ImmutableList.builder(); boolean loggingEnabled = config.get("request-logging.inbound.enabled", Boolean.class) @@ -98,7 +102,7 @@ private static HttpHandler styxHttpPipeline(StyxConfig config, HttpHandler inter .add(new HopByHopHeadersRemovingInterceptor()) .add(new RequestEnrichingInterceptor(config.styxHeaderConfig())); - return new HttpInterceptorPipeline(builder.build(), interceptorsPipeline); + return new HttpInterceptorPipeline(builder.build(), interceptorsPipeline, requestTracking); } private static HttpHandler configuredPipeline( @@ -109,6 +113,8 @@ private static HttpHandler configuredPipeline( ) { HttpPipelineFactory pipelineBuilder; + boolean requestTracking = environment.configuration().get("requestTracking", Boolean.class).orElse(false); + if (environment.configuration().get("httpPipeline", RouteHandlerDefinition.class).isPresent()) { pipelineBuilder = () -> { RouteHandlerDefinition pipelineConfig = environment.configuration().get("httpPipeline", RouteHandlerDefinition.class).get(); @@ -116,7 +122,7 @@ private static HttpHandler configuredPipeline( }; } else { Registry backendServicesRegistry = (Registry) servicesFromConfig.get("backendServiceRegistry"); - pipelineBuilder = new StaticPipelineFactory(environment, backendServicesRegistry, plugins); + pipelineBuilder = new StaticPipelineFactory(environment, backendServicesRegistry, plugins, requestTracking); } return pipelineBuilder.build(); @@ -126,13 +132,13 @@ private static ImmutableMap createBuiltinRoutingObje Environment environment, Map servicesFromConfig, Iterable plugins, - BuiltinInterceptorsFactory builtinInterceptorsFactory - ) { + BuiltinInterceptorsFactory builtinInterceptorsFactory, + boolean requestTracking) { return ImmutableMap.of( "StaticResponseHandler", new StaticResponseHandler.ConfigFactory(), "ConditionRouter", new ConditionRouter.ConfigFactory(), "BackendServiceProxy", new BackendServiceProxy.ConfigFactory(environment, backendRegistries(servicesFromConfig)), - "InterceptorPipeline", new HttpInterceptorPipeline.ConfigFactory(plugins, builtinInterceptorsFactory), + "InterceptorPipeline", new HttpInterceptorPipeline.ConfigFactory(plugins, builtinInterceptorsFactory, requestTracking), "ProxyToBackend", new ProxyToBackend.ConfigFactory(environment, new StyxBackendServiceClientFactory(environment)) ); } diff --git a/components/proxy/src/test/java/com/hotels/styx/StyxConfigTest.java b/components/proxy/src/test/java/com/hotels/styx/StyxConfigTest.java index 092bcc8b4a..5548794b0d 100644 --- a/components/proxy/src/test/java/com/hotels/styx/StyxConfigTest.java +++ b/components/proxy/src/test/java/com/hotels/styx/StyxConfigTest.java @@ -15,11 +15,9 @@ */ package com.hotels.styx; -import com.hotels.styx.infrastructure.configuration.yaml.YamlConfig; import com.hotels.styx.proxy.ProxyServerConfig; import org.testng.annotations.Test; -import static com.hotels.styx.StartupConfig.defaultStartupConfig; import static com.hotels.styx.support.matchers.IsOptional.isValue; import static java.lang.Runtime.getRuntime; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/components/proxy/src/test/java/com/hotels/styx/proxy/InterceptorPipelineBuilderTest.java b/components/proxy/src/test/java/com/hotels/styx/proxy/InterceptorPipelineBuilderTest.java index 373a51bc1c..313797f7ed 100644 --- a/components/proxy/src/test/java/com/hotels/styx/proxy/InterceptorPipelineBuilderTest.java +++ b/components/proxy/src/test/java/com/hotels/styx/proxy/InterceptorPipelineBuilderTest.java @@ -71,7 +71,7 @@ public void setUp() { @Test public void buildsPipelineWithInterceptors() throws Exception { - HttpHandler pipeline = new InterceptorPipelineBuilder(environment, plugins, handler).build(); + HttpHandler pipeline = new InterceptorPipelineBuilder(environment, plugins, handler, false).build(); LiveHttpResponse response = pipeline.handle(get("/foo").build(), HttpInterceptorContext.create()).asCompletableFuture().get(); assertThat(response.header("plug1"), isValue("1")); diff --git a/components/proxy/src/test/java/com/hotels/styx/proxy/StyxProxyTest.java b/components/proxy/src/test/java/com/hotels/styx/proxy/StyxProxyTest.java index 1d5d55475d..49b7fe0e04 100644 --- a/components/proxy/src/test/java/com/hotels/styx/proxy/StyxProxyTest.java +++ b/components/proxy/src/test/java/com/hotels/styx/proxy/StyxProxyTest.java @@ -78,7 +78,7 @@ public void startsServerWithHttpConnector() { HttpServer server = NettyServerBuilder.newBuilder() .setHttpConnector(connector(0)) - .httpHandler(new HttpInterceptorPipeline(ImmutableList.of(echoInterceptor), new StandardHttpRouter())) + .httpHandler(new HttpInterceptorPipeline(ImmutableList.of(echoInterceptor), new StandardHttpRouter(), false)) .build(); server.startAsync().awaitRunning(); assertThat("Server should be running", server.isRunning()); diff --git a/components/proxy/src/test/java/com/hotels/styx/routing/StaticPipelineBuilderTest.java b/components/proxy/src/test/java/com/hotels/styx/routing/StaticPipelineBuilderTest.java index 84f9b6acd6..c34d716f17 100644 --- a/components/proxy/src/test/java/com/hotels/styx/routing/StaticPipelineBuilderTest.java +++ b/components/proxy/src/test/java/com/hotels/styx/routing/StaticPipelineBuilderTest.java @@ -63,7 +63,7 @@ public void staticPipelineBuilderTest() { @Test public void buildsInterceptorPipelineForBackendServices() throws Exception { - HttpHandler handler = new StaticPipelineFactory(clientFactory, environment, registry, ImmutableList.of()).build(); + HttpHandler handler = new StaticPipelineFactory(clientFactory, environment, registry, ImmutableList.of(), false).build(); LiveHttpResponse response = handler.handle(get("/foo").build(), HttpInterceptorContext.create()).asCompletableFuture().get(); assertThat(response.status(), is(OK)); } @@ -75,7 +75,7 @@ public void appliesPluginsInOrderTheyAreConfigured() throws Exception { interceptor("Test-B", appendResponseHeader("X-From-Plugin", "B")) ); - HttpHandler handler = new StaticPipelineFactory(clientFactory, environment, registry, plugins).build(); + HttpHandler handler = new StaticPipelineFactory(clientFactory, environment, registry, plugins, false).build(); LiveHttpResponse response = handler.handle(get("/foo").build(), HttpInterceptorContext.create()).asCompletableFuture().get(); assertThat(response.status(), is(OK)); diff --git a/components/proxy/src/test/java/com/hotels/styx/routing/handlers/StandardHttpPipelineTest.java b/components/proxy/src/test/java/com/hotels/styx/routing/handlers/StandardHttpPipelineTest.java index 17d45fa95b..06556f4e75 100644 --- a/components/proxy/src/test/java/com/hotels/styx/routing/handlers/StandardHttpPipelineTest.java +++ b/components/proxy/src/test/java/com/hotels/styx/routing/handlers/StandardHttpPipelineTest.java @@ -20,6 +20,7 @@ import com.hotels.styx.api.HttpInterceptor; import com.hotels.styx.api.LiveHttpResponse; import com.hotels.styx.server.HttpInterceptorContext; +import com.hotels.styx.server.track.RequestTracker; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -168,7 +169,7 @@ public void sendsExceptionUponExtraSubscriptionInsideInterceptor(HttpInterceptor HttpHandler handler = (request, context) -> Eventual.of(response(OK).build()); List interceptors = singletonList(interceptor); - StandardHttpPipeline pipeline = new StandardHttpPipeline(interceptors, handler); + StandardHttpPipeline pipeline = new StandardHttpPipeline(interceptors, handler, RequestTracker.NO_OP); Eventual responseObservable = pipeline.handle(get("/").build(), HttpInterceptorContext.create()); toObservable(responseObservable).toBlocking().first(); @@ -193,27 +194,6 @@ private HttpInterceptor subscribeInPluginBeforeSubscription() { }; } - // TOOD: Mikko: Styx 2.0 API: Probably can be removed because the - // Rx Observables are not available for for API consumers. -// private HttpInterceptor reSubscribeDuringSubscriptionOriginalErrorCause() { -// return (request, chain) -> -// just(request) -// .map(chain::proceed) -// .flatMap(responseObservable -> responseObservable -// .filter(response -> false) -// .switchIfEmpty(responseObservable)); -// } - -// private HttpInterceptor reSubscribeDuringSubscription() { -// return (request, chain) -> -// just(request).map(chain::proceed) -// .flatMap(responseObservable -> { -// responseObservable.toBlocking().single(); -// -// return responseObservable; -// }); -// } - private HttpInterceptor recordingInterceptor(String name, Consumer onInterceptRequest, Consumer onInterceptResponse) { return (request, chain) -> { onInterceptRequest.accept(name); @@ -232,6 +212,6 @@ private LiveHttpResponse sendRequestTo(StandardHttpPipeline pipeline) { } private StandardHttpPipeline pipeline(HttpInterceptor... interceptors) { - return new StandardHttpPipeline(asList(interceptors), (request, context) -> Eventual.of(response(OK).build())); + return new StandardHttpPipeline(asList(interceptors), (request, context) -> Eventual.of(response(OK).build()), RequestTracker.NO_OP); } } \ No newline at end of file diff --git a/components/server/src/main/java/com/hotels/styx/server/netty/connectors/HttpPipelineHandler.java b/components/server/src/main/java/com/hotels/styx/server/netty/connectors/HttpPipelineHandler.java index 8fc147cf6b..9c5901ac8c 100644 --- a/components/server/src/main/java/com/hotels/styx/server/netty/connectors/HttpPipelineHandler.java +++ b/components/server/src/main/java/com/hotels/styx/server/netty/connectors/HttpPipelineHandler.java @@ -22,9 +22,9 @@ import com.hotels.styx.api.ContentOverflowException; import com.hotels.styx.api.HttpHandler; import com.hotels.styx.api.HttpInterceptor; +import com.hotels.styx.api.HttpResponseStatus; import com.hotels.styx.api.LiveHttpRequest; import com.hotels.styx.api.LiveHttpResponse; -import com.hotels.styx.api.HttpResponseStatus; import com.hotels.styx.api.MetricRegistry; import com.hotels.styx.api.exceptions.NoAvailableHostsException; import com.hotels.styx.api.exceptions.OriginUnreachableException; @@ -45,8 +45,6 @@ import com.hotels.styx.server.NoServiceConfiguredException; import com.hotels.styx.server.RequestProgressListener; import com.hotels.styx.server.RequestTimeoutException; -import com.hotels.styx.server.track.CurrentRequestTracker; - import com.hotels.styx.server.track.RequestTracker; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; @@ -715,7 +713,7 @@ public Builder secure(boolean secure) { return this; } - public Builder requestTracker(CurrentRequestTracker tracker) { + public Builder requestTracker(RequestTracker tracker) { this.tracker = requireNonNull(tracker); return this; } diff --git a/docs/user-guide/admin-interface.md b/docs/user-guide/admin-interface.md index f39be024f6..a3f7f64e85 100644 --- a/docs/user-guide/admin-interface.md +++ b/docs/user-guide/admin-interface.md @@ -29,7 +29,9 @@ Note that this endpoint must be externally secured. * `Threads` - a stack trace dump from all threads. -* `Current Request` - shows the state of proxied HTTP requests inside Styx. A stack trace is shown if the request is being processed in the interceptor pipeline. +* `Current Request` - shows the state of proxied HTTP requests inside Styx. + A stack trace is shown if the request is being processed in the interceptor pipeline. + This feature must be activated by `requestTracking` flag in the Styx configuration. All endpoints are available from the admin menu: diff --git a/docs/user-guide/configure-overview.md b/docs/user-guide/configure-overview.md index 8ba647f321..f4bb1741f2 100644 --- a/docs/user-guide/configure-overview.md +++ b/docs/user-guide/configure-overview.md @@ -130,6 +130,10 @@ using environment variables with the same name as the property. name: "X-Styx-Origin-Id" requestId: name: "X-Styx-Request-Id" + + # Enables request tracking. This is a debugging feature that shows information about + # each proxied request. Accepts a boolean value (true/false). + requestTracking: false ``` Without the comments, it looks like this: @@ -193,4 +197,6 @@ Without the comments, it looks like this: name: "X-Styx-Origin-Id" requestId: name: "X-Styx-Request-Id" + + requestTracking: false ``` \ No newline at end of file