From b866d6404c4a8bef11979a3e781b0d6458abdd31 Mon Sep 17 00:00:00 2001 From: Jose Montoya Date: Fri, 10 Jul 2020 09:38:16 -0500 Subject: [PATCH 1/7] grizzly-http-server: refactor to chain transformations --- rule/grizzly-http-server/pom.xml | 36 ++++---- .../server/FilterChainAgentIntercept.java | 32 ------- .../http/server/FilterChainAgentRule.java | 72 --------------- .../server/HttpServerFilterIntercept.java | 88 +++++++++++++++++++ .../http/server/HttpServerFilterRule.java | 80 +++++++++++++++++ .../grizzly/http/server/SpanAssociations.java | 68 ++++++++++++++ .../src/main/resources/otarules.mf | 2 +- 7 files changed, 258 insertions(+), 120 deletions(-) delete mode 100644 rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/FilterChainAgentIntercept.java delete mode 100644 rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/FilterChainAgentRule.java create mode 100644 rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java create mode 100644 rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java create mode 100644 rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/SpanAssociations.java diff --git a/rule/grizzly-http-server/pom.xml b/rule/grizzly-http-server/pom.xml index 0dc98daf8..1fa8c8b6e 100644 --- a/rule/grizzly-http-server/pom.xml +++ b/rule/grizzly-http-server/pom.xml @@ -59,9 +59,29 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + org.glassfish.grizzly + grizzly-framework + ${min.version} + true + + + org.glassfish.grizzly + grizzly-http + ${min.version} + true + io.opentracing.contrib @@ -76,26 +96,12 @@ test-jar test - - org.glassfish.grizzly - grizzly-framework - ${min.version} - true - provided - - - org.glassfish.grizzly - grizzly-http - ${min.version} - true - provided - org.glassfish.grizzly grizzly-http-server ${min.version} true - test + provided org.glassfish.grizzly diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/FilterChainAgentIntercept.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/FilterChainAgentIntercept.java deleted file mode 100644 index 627813d77..000000000 --- a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/FilterChainAgentIntercept.java +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright 2019 The OpenTracing Authors - * - * 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.opentracing.contrib.specialagent.rule.grizzly.http.server; - -import org.glassfish.grizzly.filterchain.FilterChainBuilder; - -import io.opentracing.contrib.grizzly.http.server.TracedFilterChainBuilder; -import io.opentracing.contrib.specialagent.AgentRuleUtil; -import io.opentracing.util.GlobalTracer; -import net.bytebuddy.asm.Advice; - -public class FilterChainAgentIntercept { - public static Object enter(final @Advice.This Object thiz) { - if (AgentRuleUtil.callerEquals(1, 3, "io.opentracing.contrib.grizzly.http.server.TracedFilterChainBuilder.build")) - return null; - - return new TracedFilterChainBuilder((FilterChainBuilder)thiz, GlobalTracer.get()).build(); - } -} \ No newline at end of file diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/FilterChainAgentRule.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/FilterChainAgentRule.java deleted file mode 100644 index d7964c0a3..000000000 --- a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/FilterChainAgentRule.java +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2019 The OpenTracing Authors - * - * 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.opentracing.contrib.specialagent.rule.grizzly.http.server; - -import static net.bytebuddy.matcher.ElementMatchers.*; - -import io.opentracing.contrib.specialagent.AgentRule; -import io.opentracing.contrib.specialagent.EarlyReturnException; -import net.bytebuddy.agent.builder.AgentBuilder; -import net.bytebuddy.agent.builder.AgentBuilder.Identified.Narrowable; -import net.bytebuddy.agent.builder.AgentBuilder.Transformer; -import net.bytebuddy.asm.Advice; -import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.dynamic.DynamicType.Builder; -import net.bytebuddy.implementation.bytecode.assign.Assigner.Typing; -import net.bytebuddy.utility.JavaModule; - -public class FilterChainAgentRule extends AgentRule { - @Override - public AgentBuilder[] buildAgentUnchained(final AgentBuilder builder) { - final Narrowable narrowable = builder.type(hasSuperType(named("org.glassfish.grizzly.filterchain.FilterChainBuilder$StatelessFilterChainBuilder"))); - return new AgentBuilder[] { - narrowable - .transform(new Transformer() { - @Override - public Builder transform(final Builder builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) { - return builder.visit(advice(typeDescription).to(OnEnter.class).on(named("build"))); - }}), - narrowable - .transform(new Transformer() { - @Override - public Builder transform(final Builder builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) { - return builder.visit(advice(typeDescription).to(OnExit.class).on(named("build"))); - }})}; - } - - public static class OnEnter { - @Advice.OnMethodEnter - public static void enter(final @ClassName String className, final @Advice.Origin String origin, final @Advice.This Object thiz) throws EarlyReturnException { - if (!isAllowed(className, origin)) - return; - - final Object filterChain = FilterChainAgentIntercept.enter(thiz); - if (filterChain != null) - throw new EarlyReturnException(filterChain); - } - } - - public static class OnExit { - @SuppressWarnings("unused") - @Advice.OnMethodExit(onThrowable = Throwable.class) - public static void exit(@Advice.Return(readOnly = false, typing = Typing.DYNAMIC) Object returned, @Advice.Thrown(readOnly = false, typing = Typing.DYNAMIC) Throwable thrown) { - if (thrown instanceof EarlyReturnException) { - returned = ((EarlyReturnException)thrown).getReturnValue(); - thrown = null; - } - } - } -} \ No newline at end of file diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java new file mode 100644 index 000000000..f28eae3ed --- /dev/null +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java @@ -0,0 +1,88 @@ +package io.opentracing.contrib.specialagent.rule.grizzly.http.server; + +import io.opentracing.Scope; +import io.opentracing.Span; +import io.opentracing.SpanContext; +import io.opentracing.Tracer; +import io.opentracing.contrib.grizzly.http.server.GizzlyHttpRequestPacketAdapter; +import io.opentracing.propagation.Format; +import io.opentracing.tag.Tags; +import io.opentracing.util.GlobalTracer; +import org.glassfish.grizzly.filterchain.FilterChainContext; +import org.glassfish.grizzly.filterchain.NextAction; +import org.glassfish.grizzly.http.HttpHeader; +import org.glassfish.grizzly.http.HttpRequestPacket; +import org.glassfish.grizzly.http.HttpResponsePacket; + +public class HttpServerFilterIntercept { + public static Scope onHandleReadEnter( + final FilterChainContext ctx, + final HttpHeader httpHeader) { + + // If we have have already started a span for this request + // If we're not reading a request, ie. an http client + if (SpanAssociations.get().hasSpanFor(ctx) || !(httpHeader instanceof HttpRequestPacket)) { + return null; + } + + Tracer tracer = GlobalTracer.get(); + final HttpRequestPacket request = (HttpRequestPacket) httpHeader; + + SpanContext extractedContext = tracer.extract(Format.Builtin.HTTP_HEADERS, + new GizzlyHttpRequestPacketAdapter(request)); + final Span span = tracer.buildSpan("HTTP::" + request.getMethod().getMethodString()) + .ignoreActiveSpan() + .asChildOf(extractedContext) + .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER) + .start(); + + Scope scope = tracer.scopeManager().activate(span); + + Tags.COMPONENT.set(span, "java-grizzly-http-server"); + Tags.HTTP_METHOD.set(span, request.getMethod().getMethodString()); + Tags.HTTP_URL.set(span, request.getRequestURI()); + + ctx.addCompletionListener(new ScopeCompletionListener(span, scope)); + + SpanAssociations.get().associateSpan(ctx, span); + + return scope; + } + + public static void onHandleReadExit( + final FilterChainContext ctx, + NextAction toReturn, + Scope scope) { + + // going async + if (scope != null && toReturn.equals(ctx.getSuspendAction())) { + scope.close(); + } + } + + public static void onPrepareResponse( + final FilterChainContext ctx, + final HttpResponsePacket response) { + Span toTag = SpanAssociations.get().retrieveSpan(ctx); + if (toTag != null) { + Tags.HTTP_STATUS.set(toTag, response.getStatus()); + } + } + + public static class ScopeCompletionListener implements FilterChainContext.CompletionListener { + private final Span span; + private final Scope scope; + + public ScopeCompletionListener(Span span, Scope scope) { + this.span = span; + this.scope = scope; + } + + @Override + public void onComplete(FilterChainContext context) { + span.finish(); + scope.close(); + SpanAssociations.get().dispose(context); + } + } +} diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java new file mode 100644 index 000000000..4842abbcb --- /dev/null +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java @@ -0,0 +1,80 @@ +package io.opentracing.contrib.specialagent.rule.grizzly.http.server; + +import io.opentracing.Scope; +import io.opentracing.contrib.specialagent.AgentRule; +import net.bytebuddy.agent.builder.AgentBuilder; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.dynamic.DynamicType; +import net.bytebuddy.utility.JavaModule; +import org.glassfish.grizzly.filterchain.FilterChainContext; +import org.glassfish.grizzly.filterchain.NextAction; +import org.glassfish.grizzly.http.HttpHeader; +import org.glassfish.grizzly.http.HttpResponsePacket; + +import static net.bytebuddy.matcher.ElementMatchers.*; + +public class HttpServerFilterRule extends AgentRule { + @Override + public AgentBuilder buildAgentChainedGlobal2(final AgentBuilder builder) { + return builder + // TODO: 7/10/20 - Figure out how to match only to HttpServerFilter but still advice HttpCodecFilter's handleRead + .type(named("org.glassfish.grizzly.http.HttpCodecFilter")) + .transform(new AgentBuilder.Transformer() { + @Override + public DynamicType.Builder transform(final DynamicType.Builder builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) { + return builder.visit(advice(typeDescription).to(HandleReadAdvice.class).on(named("handleRead") + .and(takesArgument(0, named("org.glassfish.grizzly.filterchain.FilterChainContext"))) + .and(takesArgument(1, named("org.glassfish.grizzly.http.HttpHeader"))) + .and(isPublic()))); + } + }) + .type(named("org.glassfish.grizzly.http.HttpServerFilter")) + .transform(new AgentBuilder.Transformer() { + @Override + public DynamicType.Builder transform(final DynamicType.Builder builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) { + return builder.visit(advice(typeDescription).to(PrepareResponseAdvice.class).on(named("prepareResponse") + .and(takesArgument(0, named("org.glassfish.grizzly.filterchain.FilterChainContext"))) + .and(takesArgument(1, named("org.glassfish.grizzly.http.HttpRequestPacket"))) + .and(takesArgument(2, named("org.glassfish.grizzly.http.HttpResponsePacket"))) + .and(takesArgument(3, named("org.glassfish.grizzly.http.HttpContent"))) + .and(isPrivate()))); + }}); + } + + public static class PrepareResponseAdvice { + @Advice.OnMethodExit + public static void onExit( + final @ClassName String className, + final @Advice.Origin String origin, + @Advice.Argument(0) final FilterChainContext ctx, + @Advice.Argument(2) final HttpResponsePacket response) { + if (isAllowed(className, origin)) + HttpServerFilterIntercept.onPrepareResponse(ctx, response); + } + } + + public static class HandleReadAdvice { + @Advice.OnMethodEnter + public static void onEnter( + final @ClassName String className, + final @Advice.Origin String origin, + @Advice.Argument(0) final FilterChainContext ctx, + @Advice.Argument(1) final HttpHeader httpHeader, + @Advice.Local("scope") Scope scope) { + if (isAllowed(className, origin)) + scope = HttpServerFilterIntercept.onHandleReadEnter(ctx, httpHeader); + } + + @Advice.OnMethodExit + public static void onExit( + final @ClassName String className, + final @Advice.Origin String origin, + @Advice.Argument(0) final FilterChainContext ctx, + @Advice.Return NextAction toReturn, + @Advice.Local("scope") Scope scope) { + if (isAllowed(className, origin)) + HttpServerFilterIntercept.onHandleReadExit(ctx, toReturn, scope); + } + } +} diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/SpanAssociations.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/SpanAssociations.java new file mode 100644 index 000000000..a47dcef7f --- /dev/null +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/SpanAssociations.java @@ -0,0 +1,68 @@ +/* Copyright 2020 The OpenTracing Authors + * + * 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.opentracing.contrib.specialagent.rule.grizzly.http.server; + +import io.opentracing.Span; +import org.glassfish.grizzly.filterchain.FilterChainContext; + +import java.util.Collections; +import java.util.Map; +import java.util.WeakHashMap; + +public class SpanAssociations { + + private static final SpanAssociations INSTANCE = new SpanAssociations(); + private static final Map spanAssociations = Collections.synchronizedMap(new WeakHashMap()); + + private SpanAssociations() { + } + + public static SpanAssociations get() { + return INSTANCE; + } + + /** + * This method establishes an association between an application object + * (i.e. the subject of the instrumentation) and a span. Once the + * application object is no longer being used, the association with the + * span will automatically be discarded. + * + * @param obj The application object to be associated with the span + * @param span The span + */ + public void associateSpan(Object obj, Span span) { + spanAssociations.putIfAbsent(obj, span); + } + + /** + * This method retrieves the span associated with the supplied application + * object. + * + * @param obj The application object + * @return The span, or null if no associated span exists + */ + public Span retrieveSpan(Object obj) { + return spanAssociations.get(obj); + } + + public boolean hasSpanFor(Object obj) { + return spanAssociations.containsKey(obj); + } + + public void dispose(Object obj) { + spanAssociations.remove(obj); + } +} diff --git a/rule/grizzly-http-server/src/main/resources/otarules.mf b/rule/grizzly-http-server/src/main/resources/otarules.mf index 86ae0031b..57b1b041a 100644 --- a/rule/grizzly-http-server/src/main/resources/otarules.mf +++ b/rule/grizzly-http-server/src/main/resources/otarules.mf @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -io.opentracing.contrib.specialagent.rule.grizzly.http.server.FilterChainAgentRule \ No newline at end of file +io.opentracing.contrib.specialagent.rule.grizzly.http.server.HttpServerFilterRule From 7ff0f157c732a02d1b6da75e24278f90ac7585ed Mon Sep 17 00:00:00 2001 From: Jose Montoya Date: Sat, 11 Jul 2020 12:35:01 -0500 Subject: [PATCH 2/7] grizzly-http-server: further refactor --- rule/grizzly-http-server/pom.xml | 44 ++----------- .../GizzlyHttpRequestPacketAdapter.java | 47 +++++++++++++ .../server/HttpServerFilterIntercept.java | 43 +++++------- .../http/server/HttpServerFilterRule.java | 66 ++++++++++++++----- .../grizzly/http/server/SpanAssociations.java | 7 +- .../http/server/WorkerFilterIntercept.java | 34 ++++++++++ .../grizzly/http/server/HttpServerTest.java | 16 ++--- 7 files changed, 165 insertions(+), 92 deletions(-) create mode 100644 rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/GizzlyHttpRequestPacketAdapter.java create mode 100644 rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/WorkerFilterIntercept.java diff --git a/rule/grizzly-http-server/pom.xml b/rule/grizzly-http-server/pom.xml index 1fa8c8b6e..791e2d690 100644 --- a/rule/grizzly-http-server/pom.xml +++ b/rule/grizzly-http-server/pom.xml @@ -42,15 +42,10 @@ - - org.glassfish.grizzly - grizzly-framework - org.glassfish.grizzly:grizzly-framework:[${min.version},] - org.glassfish.grizzly grizzly-http - org.glassfish.grizzly:grizzly-framework:[${min.version},] + org.glassfish.grizzly:grizzly-http:[${min.version},] @@ -59,54 +54,27 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - 8 - 8 - - - - org.glassfish.grizzly - grizzly-framework - ${min.version} - true - org.glassfish.grizzly grizzly-http ${min.version} true - - - - io.opentracing.contrib - opentracing-grizzly-http-server - ${version.opentracing.grizzly} - true - - - io.opentracing.contrib - opentracing-grizzly-http-server - ${version.opentracing.grizzly} - test-jar - test + provided org.glassfish.grizzly grizzly-http-server ${min.version} true - provided + test - org.glassfish.grizzly - grizzly-http-client - 1.15 + org.apache.httpcomponents + fluent-hc + 4.5.2 true test diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/GizzlyHttpRequestPacketAdapter.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/GizzlyHttpRequestPacketAdapter.java new file mode 100644 index 000000000..1a9e6bbbd --- /dev/null +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/GizzlyHttpRequestPacketAdapter.java @@ -0,0 +1,47 @@ +/* + * Copyright 2018 The OpenTracing Authors + * + * 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.opentracing.contrib.specialagent.rule.grizzly.http.server; + +import io.opentracing.propagation.TextMap; +import org.glassfish.grizzly.http.HttpRequestPacket; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * @author Jose Montoya + */ +public class GizzlyHttpRequestPacketAdapter implements TextMap { + private final HttpRequestPacket requestPacket; + private final Map headers; + + public GizzlyHttpRequestPacketAdapter(HttpRequestPacket requestPacket) { + this.requestPacket = requestPacket; + this.headers = new HashMap<>(requestPacket.getHeaders().size()); + for (String headerName : requestPacket.getHeaders().names()) { + headers.put(headerName, requestPacket.getHeaders().getHeader(headerName)); + } + } + + @Override + public Iterator> iterator() { + return headers.entrySet().iterator(); + } + + @Override + public void put(String key, String value) { + requestPacket.addHeader(key, value); + } +} diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java index f28eae3ed..ef51d401e 100644 --- a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java @@ -4,60 +4,51 @@ import io.opentracing.Span; import io.opentracing.SpanContext; import io.opentracing.Tracer; -import io.opentracing.contrib.grizzly.http.server.GizzlyHttpRequestPacketAdapter; import io.opentracing.propagation.Format; +import io.opentracing.propagation.TextMap; import io.opentracing.tag.Tags; import io.opentracing.util.GlobalTracer; import org.glassfish.grizzly.filterchain.FilterChainContext; import org.glassfish.grizzly.filterchain.NextAction; +import org.glassfish.grizzly.http.HttpContent; import org.glassfish.grizzly.http.HttpHeader; import org.glassfish.grizzly.http.HttpRequestPacket; import org.glassfish.grizzly.http.HttpResponsePacket; public class HttpServerFilterIntercept { - public static Scope onHandleReadEnter( + public static void onHandleReadExit( final FilterChainContext ctx, - final HttpHeader httpHeader) { + NextAction toReturn) { + // See: org.glassfish.grizzly.filterchain.InvokeAction.TYPE // If we have have already started a span for this request // If we're not reading a request, ie. an http client - if (SpanAssociations.get().hasSpanFor(ctx) || !(httpHeader instanceof HttpRequestPacket)) { - return null; + if (toReturn.type() != 0 || !(ctx.getMessage() instanceof HttpContent) || SpanAssociations.get().hasSpanFor(ctx)) { + return; } Tracer tracer = GlobalTracer.get(); - final HttpRequestPacket request = (HttpRequestPacket) httpHeader; + final HttpRequestPacket request = (HttpRequestPacket) ((HttpContent) ctx.getMessage()).getHttpHeader(); + TextMap adapter = new GizzlyHttpRequestPacketAdapter(request); SpanContext extractedContext = tracer.extract(Format.Builtin.HTTP_HEADERS, - new GizzlyHttpRequestPacketAdapter(request)); + adapter); + final Span span = tracer.buildSpan("HTTP::" + request.getMethod().getMethodString()) .ignoreActiveSpan() .asChildOf(extractedContext) .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER) .start(); - Scope scope = tracer.scopeManager().activate(span); +// Scope scope = tracer.scopeManager().activate(span); Tags.COMPONENT.set(span, "java-grizzly-http-server"); Tags.HTTP_METHOD.set(span, request.getMethod().getMethodString()); Tags.HTTP_URL.set(span, request.getRequestURI()); - ctx.addCompletionListener(new ScopeCompletionListener(span, scope)); + ctx.addCompletionListener(new ScopeCompletionListener(span)); SpanAssociations.get().associateSpan(ctx, span); - - return scope; - } - - public static void onHandleReadExit( - final FilterChainContext ctx, - NextAction toReturn, - Scope scope) { - - // going async - if (scope != null && toReturn.equals(ctx.getSuspendAction())) { - scope.close(); - } } public static void onPrepareResponse( @@ -71,17 +62,17 @@ public static void onPrepareResponse( public static class ScopeCompletionListener implements FilterChainContext.CompletionListener { private final Span span; - private final Scope scope; +// private final Scope scope; - public ScopeCompletionListener(Span span, Scope scope) { + public ScopeCompletionListener(Span span) { this.span = span; - this.scope = scope; +// this.scope = scope; } @Override public void onComplete(FilterChainContext context) { span.finish(); - scope.close(); +// scope.close(); SpanAssociations.get().dispose(context); } } diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java index 4842abbcb..b1c19aa96 100644 --- a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java @@ -6,30 +6,27 @@ import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.dynamic.DynamicType; +import net.bytebuddy.matcher.StringMatcher; import net.bytebuddy.utility.JavaModule; import org.glassfish.grizzly.filterchain.FilterChainContext; import org.glassfish.grizzly.filterchain.NextAction; -import org.glassfish.grizzly.http.HttpHeader; import org.glassfish.grizzly.http.HttpResponsePacket; import static net.bytebuddy.matcher.ElementMatchers.*; public class HttpServerFilterRule extends AgentRule { @Override - public AgentBuilder buildAgentChainedGlobal2(final AgentBuilder builder) { + public AgentBuilder buildAgentChainedGlobal1(final AgentBuilder builder) { return builder - // TODO: 7/10/20 - Figure out how to match only to HttpServerFilter but still advice HttpCodecFilter's handleRead - .type(named("org.glassfish.grizzly.http.HttpCodecFilter")) + .type(named("org.glassfish.grizzly.http.HttpServerFilter")) .transform(new AgentBuilder.Transformer() { @Override public DynamicType.Builder transform(final DynamicType.Builder builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) { return builder.visit(advice(typeDescription).to(HandleReadAdvice.class).on(named("handleRead") .and(takesArgument(0, named("org.glassfish.grizzly.filterchain.FilterChainContext"))) - .and(takesArgument(1, named("org.glassfish.grizzly.http.HttpHeader"))) .and(isPublic()))); } }) - .type(named("org.glassfish.grizzly.http.HttpServerFilter")) .transform(new AgentBuilder.Transformer() { @Override public DynamicType.Builder transform(final DynamicType.Builder builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) { @@ -39,42 +36,79 @@ public DynamicType.Builder transform(final DynamicType.Builder builder, fi .and(takesArgument(2, named("org.glassfish.grizzly.http.HttpResponsePacket"))) .and(takesArgument(3, named("org.glassfish.grizzly.http.HttpContent"))) .and(isPrivate()))); - }}); + } + }) + + .type(hasSuperType(named("org.glassfish.grizzly.filterchain.BaseFilter")) + // common grizzly filters + .and(not(named("org.glassfish.grizzly.filterchain.TransportFilter"))) + .and(not(named("org.glassfish.grizzly.nio.transport.TCPNIOTransportFilter"))) + // TODO: 7/11/20 Figure out why HttpServerFilter still matches + .and(not(named("org.glassfish.grizzly.http.HttpServerFilter"))) + .and(not(named("org.glassfish.grizzly.utils.IdleTimeoutFilter"))) + .and(not(named("org.glassfish.grizzly.http.server.FileCacheFilter"))) + ) + .transform(new AgentBuilder.Transformer() { + @Override + public DynamicType.Builder transform(final DynamicType.Builder builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) { + return builder.visit(advice(typeDescription).to(WorkerHandleReadAdvice.class).on(named("handleRead") + .and(takesArgument(0, named("org.glassfish.grizzly.filterchain.FilterChainContext"))) + .and(isPublic()))); + } + }); } - public static class PrepareResponseAdvice { + public static class HandleReadAdvice { @Advice.OnMethodExit public static void onExit( final @ClassName String className, final @Advice.Origin String origin, @Advice.Argument(0) final FilterChainContext ctx, - @Advice.Argument(2) final HttpResponsePacket response) { + @Advice.Return NextAction toReturn) { if (isAllowed(className, origin)) - HttpServerFilterIntercept.onPrepareResponse(ctx, response); + HttpServerFilterIntercept.onHandleReadExit(ctx, toReturn); } } - public static class HandleReadAdvice { + public static class WorkerHandleReadAdvice { @Advice.OnMethodEnter public static void onEnter( final @ClassName String className, final @Advice.Origin String origin, + final @Advice.This Object thiz, @Advice.Argument(0) final FilterChainContext ctx, - @Advice.Argument(1) final HttpHeader httpHeader, @Advice.Local("scope") Scope scope) { + + // manually filtering HttpServerFilter + if (new StringMatcher("org.glassfish.grizzly.http.HttpServerFilter", + StringMatcher.Mode.EQUALS_FULLY).matches(thiz.getClass().getName())) { + return; + } + if (isAllowed(className, origin)) - scope = HttpServerFilterIntercept.onHandleReadEnter(ctx, httpHeader); + scope = WorkerFilterIntercept.onHandleReadEnter(ctx); } @Advice.OnMethodExit public static void onExit( final @ClassName String className, final @Advice.Origin String origin, - @Advice.Argument(0) final FilterChainContext ctx, - @Advice.Return NextAction toReturn, @Advice.Local("scope") Scope scope) { if (isAllowed(className, origin)) - HttpServerFilterIntercept.onHandleReadExit(ctx, toReturn, scope); + WorkerFilterIntercept.onHandleReadExit(scope); + } + } + + public static class PrepareResponseAdvice { + @Advice.OnMethodExit + public static void onExit( + final @ClassName String className, + final @Advice.Origin String origin, + @Advice.Argument(0) final FilterChainContext ctx, + @Advice.Argument(2) final HttpResponsePacket response) { + if (isAllowed(className, origin)) + HttpServerFilterIntercept.onPrepareResponse(ctx, response); } + } } diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/SpanAssociations.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/SpanAssociations.java index a47dcef7f..fe90f66ef 100644 --- a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/SpanAssociations.java +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/SpanAssociations.java @@ -16,12 +16,15 @@ package io.opentracing.contrib.specialagent.rule.grizzly.http.server; import io.opentracing.Span; -import org.glassfish.grizzly.filterchain.FilterChainContext; import java.util.Collections; import java.util.Map; import java.util.WeakHashMap; +/** + * This class provides span context capabilities. Based on + * https://github.com/opentracing-contrib/java-agent/blob/release-0.5.0/opentracing-agent/src/main/java/io/opentracing/contrib/agent/OpenTracingHelper.java + */ public class SpanAssociations { private static final SpanAssociations INSTANCE = new SpanAssociations(); @@ -44,7 +47,7 @@ public static SpanAssociations get() { * @param span The span */ public void associateSpan(Object obj, Span span) { - spanAssociations.putIfAbsent(obj, span); + spanAssociations.put(obj, span); } /** diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/WorkerFilterIntercept.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/WorkerFilterIntercept.java new file mode 100644 index 000000000..86e833d04 --- /dev/null +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/WorkerFilterIntercept.java @@ -0,0 +1,34 @@ +package io.opentracing.contrib.specialagent.rule.grizzly.http.server; + +import io.opentracing.Scope; +import io.opentracing.Span; +import io.opentracing.SpanContext; +import io.opentracing.Tracer; +import io.opentracing.propagation.Format; +import io.opentracing.propagation.TextMap; +import io.opentracing.tag.Tags; +import io.opentracing.util.GlobalTracer; +import org.glassfish.grizzly.filterchain.FilterChainContext; +import org.glassfish.grizzly.filterchain.NextAction; +import org.glassfish.grizzly.http.HttpContent; +import org.glassfish.grizzly.http.HttpHeader; +import org.glassfish.grizzly.http.HttpRequestPacket; +import org.glassfish.grizzly.http.HttpResponsePacket; + +public class WorkerFilterIntercept { + public static Scope onHandleReadEnter( + final FilterChainContext ctx) { + Span span = SpanAssociations.get().retrieveSpan(ctx); + if (span != null) { + return GlobalTracer.get().scopeManager().activate(span); + } + + return null; + } + + public static void onHandleReadExit(Scope scope) { + if (scope != null) { + scope.close(); + } + } +} diff --git a/rule/grizzly-http-server/src/test/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerTest.java b/rule/grizzly-http-server/src/test/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerTest.java index a105334df..39cb716f8 100644 --- a/rule/grizzly-http-server/src/test/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerTest.java +++ b/rule/grizzly-http-server/src/test/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerTest.java @@ -15,11 +15,10 @@ package io.opentracing.contrib.specialagent.rule.grizzly.http.server; -import static org.glassfish.grizzly.http.server.NetworkListener.*; +import static org.glassfish.grizzly.http.server.NetworkListener.DEFAULT_NETWORK_HOST; import static org.junit.Assert.*; import java.io.IOException; -import java.net.URL; import java.util.List; import org.glassfish.grizzly.http.server.HttpHandler; @@ -32,9 +31,6 @@ import org.junit.Test; import org.junit.runner.RunWith; -import com.ning.http.client.AsyncHttpClient; - -import io.opentracing.contrib.grizzly.http.server.AbstractHttpTest; import io.opentracing.contrib.specialagent.AgentRunner; import io.opentracing.mock.MockSpan; import io.opentracing.mock.MockTracer; @@ -43,7 +39,9 @@ * @author Jose Montoya */ @RunWith(AgentRunner.class) -public class HttpServerTest extends AbstractHttpTest { +public class HttpServerTest { + protected static final int PORT = 18906; + protected static final String LOCALHOST = "localhost"; private HttpServer httpServer; @Before @@ -73,10 +71,8 @@ public void service(final Request request, final Response response) throws Excep } }); - try (final AsyncHttpClient client = new AsyncHttpClient()) { - final com.ning.http.client.Response response = client.prepareGet(new URL("http", LOCALHOST, PORT, "/").toString()).execute().get(); - assertEquals(201, response.getStatusCode()); - } + final org.apache.http.client.fluent.Response response = org.apache.http.client.fluent.Request.Get("http://" + LOCALHOST + ":" + PORT + "/").addHeader("beep", "boop").execute(); + assertEquals(201, response.returnResponse().getStatusLine().getStatusCode()); final List spans = tracer.finishedSpans(); assertEquals(1, spans.size()); From 689faf5c8bffeb72fe0fe438b17f1eb34b3f2c68 Mon Sep 17 00:00:00 2001 From: Jose Montoya Date: Sat, 11 Jul 2020 12:56:37 -0500 Subject: [PATCH 3/7] grizzly-http-server: fixes class not found --- .../server/HttpServerFilterIntercept.java | 23 ++++++++----------- .../http/server/HttpServerFilterRule.java | 14 +++++------ .../http/server/WorkerFilterIntercept.java | 2 +- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java index ef51d401e..b59320565 100644 --- a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java @@ -1,6 +1,5 @@ package io.opentracing.contrib.specialagent.rule.grizzly.http.server; -import io.opentracing.Scope; import io.opentracing.Span; import io.opentracing.SpanContext; import io.opentracing.Tracer; @@ -11,19 +10,20 @@ import org.glassfish.grizzly.filterchain.FilterChainContext; import org.glassfish.grizzly.filterchain.NextAction; import org.glassfish.grizzly.http.HttpContent; -import org.glassfish.grizzly.http.HttpHeader; import org.glassfish.grizzly.http.HttpRequestPacket; import org.glassfish.grizzly.http.HttpResponsePacket; public class HttpServerFilterIntercept { public static void onHandleReadExit( - final FilterChainContext ctx, - NextAction toReturn) { + final Object ctxObj, + Object toReturn) { + FilterChainContext ctx = (FilterChainContext) ctxObj; + + // If not continuing to process // See: org.glassfish.grizzly.filterchain.InvokeAction.TYPE // If we have have already started a span for this request - // If we're not reading a request, ie. an http client - if (toReturn.type() != 0 || !(ctx.getMessage() instanceof HttpContent) || SpanAssociations.get().hasSpanFor(ctx)) { + if (!(ctx.getMessage() instanceof HttpContent) || ((NextAction) toReturn).type() != 0 || SpanAssociations.get().hasSpanFor(ctx)) { return; } @@ -40,8 +40,6 @@ public static void onHandleReadExit( .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER) .start(); -// Scope scope = tracer.scopeManager().activate(span); - Tags.COMPONENT.set(span, "java-grizzly-http-server"); Tags.HTTP_METHOD.set(span, request.getMethod().getMethodString()); Tags.HTTP_URL.set(span, request.getRequestURI()); @@ -52,27 +50,24 @@ public static void onHandleReadExit( } public static void onPrepareResponse( - final FilterChainContext ctx, - final HttpResponsePacket response) { + final Object ctx, + final Object response) { Span toTag = SpanAssociations.get().retrieveSpan(ctx); if (toTag != null) { - Tags.HTTP_STATUS.set(toTag, response.getStatus()); + Tags.HTTP_STATUS.set(toTag, ((HttpResponsePacket) response).getStatus()); } } public static class ScopeCompletionListener implements FilterChainContext.CompletionListener { private final Span span; -// private final Scope scope; public ScopeCompletionListener(Span span) { this.span = span; -// this.scope = scope; } @Override public void onComplete(FilterChainContext context) { span.finish(); -// scope.close(); SpanAssociations.get().dispose(context); } } diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java index b1c19aa96..25b109984 100644 --- a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java @@ -6,11 +6,9 @@ import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.dynamic.DynamicType; +import net.bytebuddy.implementation.bytecode.assign.Assigner; import net.bytebuddy.matcher.StringMatcher; import net.bytebuddy.utility.JavaModule; -import org.glassfish.grizzly.filterchain.FilterChainContext; -import org.glassfish.grizzly.filterchain.NextAction; -import org.glassfish.grizzly.http.HttpResponsePacket; import static net.bytebuddy.matcher.ElementMatchers.*; @@ -63,8 +61,8 @@ public static class HandleReadAdvice { public static void onExit( final @ClassName String className, final @Advice.Origin String origin, - @Advice.Argument(0) final FilterChainContext ctx, - @Advice.Return NextAction toReturn) { + @Advice.Argument(0) final Object ctx, + @Advice.Return Object toReturn) { if (isAllowed(className, origin)) HttpServerFilterIntercept.onHandleReadExit(ctx, toReturn); } @@ -76,7 +74,7 @@ public static void onEnter( final @ClassName String className, final @Advice.Origin String origin, final @Advice.This Object thiz, - @Advice.Argument(0) final FilterChainContext ctx, + @Advice.Argument(value = 0, typing = Assigner.Typing.DYNAMIC) final Object ctx, @Advice.Local("scope") Scope scope) { // manually filtering HttpServerFilter @@ -104,8 +102,8 @@ public static class PrepareResponseAdvice { public static void onExit( final @ClassName String className, final @Advice.Origin String origin, - @Advice.Argument(0) final FilterChainContext ctx, - @Advice.Argument(2) final HttpResponsePacket response) { + @Advice.Argument(value = 0, typing = Assigner.Typing.DYNAMIC) final Object ctx, + @Advice.Argument(value = 2, typing = Assigner.Typing.DYNAMIC) final Object response) { if (isAllowed(className, origin)) HttpServerFilterIntercept.onPrepareResponse(ctx, response); } diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/WorkerFilterIntercept.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/WorkerFilterIntercept.java index 86e833d04..096b1333c 100644 --- a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/WorkerFilterIntercept.java +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/WorkerFilterIntercept.java @@ -17,7 +17,7 @@ public class WorkerFilterIntercept { public static Scope onHandleReadEnter( - final FilterChainContext ctx) { + final Object ctx) { Span span = SpanAssociations.get().retrieveSpan(ctx); if (span != null) { return GlobalTracer.get().scopeManager().activate(span); From 471d635afe0dde73e113dda85a9ad20acfa82f34 Mon Sep 17 00:00:00 2001 From: Jose Montoya Date: Sat, 11 Jul 2020 16:44:11 -0500 Subject: [PATCH 4/7] grizzly-http-server: use instrumentation decorator --- rule/grizzly-http-server/pom.xml | 16 +++++++++++++++- .../http/server/HttpServerFilterIntercept.java | 16 ++++++---------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/rule/grizzly-http-server/pom.xml b/rule/grizzly-http-server/pom.xml index 791e2d690..144b87b32 100644 --- a/rule/grizzly-http-server/pom.xml +++ b/rule/grizzly-http-server/pom.xml @@ -28,7 +28,7 @@ grizzly:http-server 2.3.35 - 0.1.3 + 0.1.4-SNAPSHOT @@ -57,6 +57,20 @@ + + + io.opentracing.contrib + opentracing-grizzly-http-server + ${version.opentracing.grizzly} + true + + + io.opentracing.contrib + opentracing-grizzly-http-server + ${version.opentracing.grizzly} + test-jar + test + org.glassfish.grizzly grizzly-http diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java index b59320565..ddee00aa8 100644 --- a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java @@ -3,6 +3,7 @@ import io.opentracing.Span; import io.opentracing.SpanContext; import io.opentracing.Tracer; +import io.opentracing.contrib.grizzly.http.server.GrizzlyServerSpanDecorator; import io.opentracing.propagation.Format; import io.opentracing.propagation.TextMap; import io.opentracing.tag.Tags; @@ -37,15 +38,10 @@ public static void onHandleReadExit( final Span span = tracer.buildSpan("HTTP::" + request.getMethod().getMethodString()) .ignoreActiveSpan() .asChildOf(extractedContext) - .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER) .start(); - Tags.COMPONENT.set(span, "java-grizzly-http-server"); - Tags.HTTP_METHOD.set(span, request.getMethod().getMethodString()); - Tags.HTTP_URL.set(span, request.getRequestURI()); - - ctx.addCompletionListener(new ScopeCompletionListener(span)); - + GrizzlyServerSpanDecorator.STANDARD_TAGS.onRequest(request, span); + ctx.addCompletionListener(new SpanCompletionListener(span)); SpanAssociations.get().associateSpan(ctx, span); } @@ -54,14 +50,14 @@ public static void onPrepareResponse( final Object response) { Span toTag = SpanAssociations.get().retrieveSpan(ctx); if (toTag != null) { - Tags.HTTP_STATUS.set(toTag, ((HttpResponsePacket) response).getStatus()); + GrizzlyServerSpanDecorator.STANDARD_TAGS.onResponse((HttpResponsePacket) response, toTag); } } - public static class ScopeCompletionListener implements FilterChainContext.CompletionListener { + public static class SpanCompletionListener implements FilterChainContext.CompletionListener { private final Span span; - public ScopeCompletionListener(Span span) { + public SpanCompletionListener(Span span) { this.span = span; } From 425994878801f92092f1988c1b124996eeeff552 Mon Sep 17 00:00:00 2001 From: Jose Montoya Date: Sat, 11 Jul 2020 17:04:23 -0500 Subject: [PATCH 5/7] mule: remove http-service --- opentracing-specialagent/pom.xml | 7 - rule/mule-4-http-service/README.md | 11 -- rule/mule-4-http-service/pom.xml | 135 ------------------ .../http/MuleFilterChainAgentIntercept.java | 31 ---- .../http/MuleFilterChainAgentRule.java | 72 ---------- .../http/TracedMuleFilterChainBuilder.java | 41 ------ .../src/main/resources/otarules.mf | 15 -- .../mule4/service/http/HttpServiceTest.java | 75 ---------- rule/pom.xml | 1 - test/mule/mule-4.2.2/pom.xml | 2 +- 10 files changed, 1 insertion(+), 389 deletions(-) delete mode 100644 rule/mule-4-http-service/README.md delete mode 100644 rule/mule-4-http-service/pom.xml delete mode 100644 rule/mule-4-http-service/src/main/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/MuleFilterChainAgentIntercept.java delete mode 100644 rule/mule-4-http-service/src/main/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/MuleFilterChainAgentRule.java delete mode 100644 rule/mule-4-http-service/src/main/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/TracedMuleFilterChainBuilder.java delete mode 100644 rule/mule-4-http-service/src/main/resources/otarules.mf delete mode 100644 rule/mule-4-http-service/src/test/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/HttpServiceTest.java diff --git a/opentracing-specialagent/pom.xml b/opentracing-specialagent/pom.xml index b06113544..52c24bdc5 100644 --- a/opentracing-specialagent/pom.xml +++ b/opentracing-specialagent/pom.xml @@ -470,13 +470,6 @@ true provided - - io.opentracing.contrib.specialagent.rule - mule-4-http-service - ${project.version} - true - provided - io.opentracing.contrib.specialagent.rule mule-4-module-artifact diff --git a/rule/mule-4-http-service/README.md b/rule/mule-4-http-service/README.md deleted file mode 100644 index 88980a107..000000000 --- a/rule/mule-4-http-service/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# SpecialAgent Rule for Mule 4 HTTP Service - -**Rule Name:** `mule:http-service:4` - -## Compatibility - -```xml -org.mule.runtime -mule-module-artifact -[4.2.2,4.0.0-M5),(4.0.0-M5.2,LATEST] -``` \ No newline at end of file diff --git a/rule/mule-4-http-service/pom.xml b/rule/mule-4-http-service/pom.xml deleted file mode 100644 index c997eade0..000000000 --- a/rule/mule-4-http-service/pom.xml +++ /dev/null @@ -1,135 +0,0 @@ - - - 4.0.0 - - io.opentracing.contrib.specialagent.rule - rule - 1.7.4-SNAPSHOT - - mule-4-http-service - SpecialAgent Rule for Mule 4 HTTP Service - - 1.8 - 1.8 - mule:http-service:4 - 1.4.7 - org.mule.services:mule-service-http:[${min.version},4.0.0-M5),(4.0.0-M5.2,] - 0.1.3 - 4.2.2 - 2.11.2 - - - - org.mule.services - mule-service-http - ${min.version} - true - provided - - - - io.opentracing.contrib - opentracing-grizzly-http-server - ${version.opentracing.grizzly.http.server} - true - - - io.opentracing.contrib - opentracing-grizzly-http-server - ${version.opentracing.grizzly.http.server} - test-jar - test - - - org.mule.runtime - mule-core - ${version.mule} - true - test - - - org.mule.runtime - mule-extensions-api - 1.2.2 - true - test - - - org.mule.runtime - mule-service-http-api - ${version.mule} - true - test - - - org.mule.tests - mule-tests-unit - ${version.mule} - true - test - - - org.apache.logging.log4j - log4j-api - ${version.apache-logging} - true - test - - - org.apache.logging.log4j - log4j-core - ${version.apache-logging} - true - test - - - org.apache.httpcomponents - fluent-hc - 4.5.2 - true - test - - - - - anypoint-exchange-v2 - Anypoint Exchange - https://maven.anypoint.mulesoft.com/api/v2/maven - default - - - mulesoft-releases - MuleSoft Releases Repository - https://repository.mulesoft.org/releases/ - default - - - - - mulesoft-releases - mulesoft release repository - default - https://repository.mulesoft.org/releases/ - - false - - - - \ No newline at end of file diff --git a/rule/mule-4-http-service/src/main/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/MuleFilterChainAgentIntercept.java b/rule/mule-4-http-service/src/main/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/MuleFilterChainAgentIntercept.java deleted file mode 100644 index 5a1f90cef..000000000 --- a/rule/mule-4-http-service/src/main/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/MuleFilterChainAgentIntercept.java +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright 2019 The OpenTracing Authors - * - * 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.opentracing.contrib.specialagent.rule.mule4.service.http; - -import org.glassfish.grizzly.filterchain.FilterChainBuilder; - -import io.opentracing.contrib.specialagent.AgentRuleUtil; -import io.opentracing.util.GlobalTracer; -import net.bytebuddy.asm.Advice; - -public class MuleFilterChainAgentIntercept { - public static Object enter(final @Advice.This Object thiz) { - if (AgentRuleUtil.callerEquals(1, 3, "io.opentracing.contrib.grizzly.http.server.TracedFilterChainBuilder.build")) - return null; - - return new TracedMuleFilterChainBuilder((FilterChainBuilder)thiz, GlobalTracer.get()).build(); - } -} \ No newline at end of file diff --git a/rule/mule-4-http-service/src/main/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/MuleFilterChainAgentRule.java b/rule/mule-4-http-service/src/main/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/MuleFilterChainAgentRule.java deleted file mode 100644 index 84642797a..000000000 --- a/rule/mule-4-http-service/src/main/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/MuleFilterChainAgentRule.java +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright 2019 The OpenTracing Authors - * - * 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.opentracing.contrib.specialagent.rule.mule4.service.http; - -import static net.bytebuddy.matcher.ElementMatchers.*; - -import io.opentracing.contrib.specialagent.AgentRule; -import io.opentracing.contrib.specialagent.EarlyReturnException; -import net.bytebuddy.agent.builder.AgentBuilder; -import net.bytebuddy.agent.builder.AgentBuilder.Identified.Narrowable; -import net.bytebuddy.agent.builder.AgentBuilder.Transformer; -import net.bytebuddy.asm.Advice; -import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.dynamic.DynamicType.Builder; -import net.bytebuddy.implementation.bytecode.assign.Assigner.Typing; -import net.bytebuddy.utility.JavaModule; - -public class MuleFilterChainAgentRule extends AgentRule { - @Override - public AgentBuilder[] buildAgentUnchained(final AgentBuilder builder) { - final Narrowable narrowable = builder.type(named("org.glassfish.grizzly.filterchain.FilterChainBuilder$StatelessFilterChainBuilder")); - return new AgentBuilder[] { - narrowable - .transform(new Transformer() { - @Override - public Builder transform(final Builder builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) { - return builder.visit(advice(typeDescription).to(OnEnter.class).on(named("build"))); - }}), - narrowable - .transform(new Transformer() { - @Override - public Builder transform(final Builder builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) { - return builder.visit(advice(typeDescription).to(OnExit.class).on(named("build"))); - }})}; - } - - public static class OnEnter { - @Advice.OnMethodEnter - public static void enter(final @ClassName String className, final @Advice.Origin String origin, final @Advice.This Object thiz) throws EarlyReturnException { - if (!isAllowed(className, origin)) - return; - - final Object filterChain = MuleFilterChainAgentIntercept.enter(thiz); - if (filterChain != null) - throw new EarlyReturnException(filterChain); - } - } - - public static class OnExit { - @SuppressWarnings("unused") - @Advice.OnMethodExit(onThrowable = Throwable.class) - public static void exit(@Advice.Return(readOnly = false, typing = Typing.DYNAMIC) Object returned, @Advice.Thrown(readOnly = false, typing = Typing.DYNAMIC) Throwable thrown) { - if (thrown instanceof EarlyReturnException) { - returned = ((EarlyReturnException)thrown).getReturnValue(); - thrown = null; - } - } - } -} \ No newline at end of file diff --git a/rule/mule-4-http-service/src/main/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/TracedMuleFilterChainBuilder.java b/rule/mule-4-http-service/src/main/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/TracedMuleFilterChainBuilder.java deleted file mode 100644 index c9b178009..000000000 --- a/rule/mule-4-http-service/src/main/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/TracedMuleFilterChainBuilder.java +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright 2019 The OpenTracing Authors - * - * 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.opentracing.contrib.specialagent.rule.mule4.service.http; - -import org.glassfish.grizzly.filterchain.FilterChain; -import org.glassfish.grizzly.filterchain.FilterChainBuilder; -import org.mule.service.http.impl.service.server.grizzly.GrizzlyRequestDispatcherFilter; - -import io.opentracing.Tracer; -import io.opentracing.contrib.grizzly.http.server.TracedFilterChainBuilder; - -public class TracedMuleFilterChainBuilder extends TracedFilterChainBuilder { - public TracedMuleFilterChainBuilder(final FilterChainBuilder builder, final Tracer tracer) { - super(builder, tracer); - } - - @Override - public FilterChain build() { - final int dispatcherFilter = this.indexOfType(GrizzlyRequestDispatcherFilter.class); - if (dispatcherFilter != -1) { - // If contains an GrizzlyRequestDispatcherFilter - // @see https://github.com/mulesoft/mule-http-service/blob/1.4.7/src/main/java/org/mule/service/http/impl/service/server/grizzly/GrizzlyServerManager.java#L111 - addTracingFiltersAt(4); - } - - return super.build(); - } -} \ No newline at end of file diff --git a/rule/mule-4-http-service/src/main/resources/otarules.mf b/rule/mule-4-http-service/src/main/resources/otarules.mf deleted file mode 100644 index 0ea05b137..000000000 --- a/rule/mule-4-http-service/src/main/resources/otarules.mf +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2019 The OpenTracing Authors -# -# 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. - -io.opentracing.contrib.specialagent.rule.mule4.service.http.MuleFilterChainAgentRule diff --git a/rule/mule-4-http-service/src/test/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/HttpServiceTest.java b/rule/mule-4-http-service/src/test/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/HttpServiceTest.java deleted file mode 100644 index 4eeec67c0..000000000 --- a/rule/mule-4-http-service/src/test/java/io/opentracing/contrib/specialagent/rule/mule4/service/http/HttpServiceTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright 2020 The OpenTracing Authors - * - * 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.opentracing.contrib.specialagent.rule.mule4.service.http; - -import static org.junit.Assert.*; - -import org.apache.http.client.fluent.Request; -import org.apache.http.client.fluent.Response; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mule.runtime.core.api.util.ClassUtils; -import org.mule.runtime.http.api.server.HttpServer; -import org.mule.runtime.http.api.server.HttpServerConfiguration; -import org.mule.service.http.impl.service.HttpServiceImplementation; -import org.mule.tck.SimpleUnitTestSupportSchedulerService; -import org.mule.tck.junit4.AbstractMuleTestCase; - -import io.opentracing.contrib.specialagent.AgentRunner; -import io.opentracing.mock.MockTracer; - -@RunWith(AgentRunner.class) -public class HttpServiceTest extends AbstractMuleTestCase { - private static final String HOST = "localhost"; - private static final int PORT = 9875; - private HttpServiceImplementation service; - private SimpleUnitTestSupportSchedulerService schedulerService; - private HttpServer server; - - @Before - public void before(final MockTracer tracer) throws Exception { - tracer.reset(); - - schedulerService = new SimpleUnitTestSupportSchedulerService(); - service = (HttpServiceImplementation)ClassUtils.instantiateClass(HttpServiceImplementation.class.getName(), new Object[] {schedulerService}, this.getClass().getClassLoader()); - service.start(); - - server = service.getServerFactory().create(new HttpServerConfiguration.Builder().setHost(HOST).setPort(PORT).setName("test-server").build()); - server.start(); - } - - @After - public void after() throws Exception { - if (server != null) - server.stop(); - - if (service != null) - service.stop(); - - if (schedulerService != null) - schedulerService.stop(); - } - - @Test - // @AgentRunner.TestConfig(verbose = true) - public void httpServiceTest(final MockTracer tracer) throws Exception { - final Response response = Request.Get("http://" + HOST + ":" + PORT + "/").execute(); - assertEquals(response.returnResponse().getStatusLine().getStatusCode(), 503); - assertEquals(1, tracer.finishedSpans().size()); - } -} \ No newline at end of file diff --git a/rule/pom.xml b/rule/pom.xml index 6a2ee32a6..278411863 100644 --- a/rule/pom.xml +++ b/rule/pom.xml @@ -69,7 +69,6 @@ apache-httpclient lettuce mule-4-core - mule-4-http-service mule-4-module-artifact spring-webflux redisson diff --git a/test/mule/mule-4.2.2/pom.xml b/test/mule/mule-4.2.2/pom.xml index b52ec5a87..d6b7a1696 100644 --- a/test/mule/mule-4.2.2/pom.xml +++ b/test/mule/mule-4.2.2/pom.xml @@ -31,7 +31,7 @@ 4.2.2 ${project.basedir}/src/test/mule-home FINE - -Dsa.integration.*.disable -Dsa.integration.mule*.enable -Dsa.integration.grizzly:http-client.enable -Dsa.integration.jdbc.enable + -Dsa.integration.*.disable -Dsa.integration.mule*.enable -Dsa.integration.grizzly:http-server.enable -Dsa.integration.grizzly:http-client.enable -Dsa.integration.jdbc.enable From 286176395422281adb0290979696ac4cd7b732f0 Mon Sep 17 00:00:00 2001 From: Jose Montoya Date: Sat, 11 Jul 2020 20:16:36 -0500 Subject: [PATCH 6/7] grizzly-http-server: minor refactor --- rule/grizzly-http-server/pom.xml | 8 +-- .../http/server/HttpServerFilterRule.java | 62 +++++++++++-------- .../grizzly/http/server/HttpServerTest.java | 15 +++-- 3 files changed, 50 insertions(+), 35 deletions(-) diff --git a/rule/grizzly-http-server/pom.xml b/rule/grizzly-http-server/pom.xml index 144b87b32..cd2c1b4b4 100644 --- a/rule/grizzly-http-server/pom.xml +++ b/rule/grizzly-http-server/pom.xml @@ -28,7 +28,7 @@ grizzly:http-server 2.3.35 - 0.1.4-SNAPSHOT + 0.2.0 @@ -86,9 +86,9 @@ test - org.apache.httpcomponents - fluent-hc - 4.5.2 + org.glassfish.grizzly + grizzly-http-client + 1.15 true test diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java index 25b109984..22d4993a9 100644 --- a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterRule.java @@ -1,5 +1,7 @@ package io.opentracing.contrib.specialagent.rule.grizzly.http.server; +import io.opentracing.contrib.specialagent.Level; +import io.opentracing.contrib.specialagent.Logger; import io.opentracing.Scope; import io.opentracing.contrib.specialagent.AgentRule; import net.bytebuddy.agent.builder.AgentBuilder; @@ -7,12 +9,15 @@ import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.implementation.bytecode.assign.Assigner; -import net.bytebuddy.matcher.StringMatcher; import net.bytebuddy.utility.JavaModule; import static net.bytebuddy.matcher.ElementMatchers.*; public class HttpServerFilterRule extends AgentRule { + public static final Logger logger = Logger.getLogger(HttpServerFilterRule.class); + private static final String FILTER_CHAIN_CONTEXT = "org.glassfish.grizzly.filterchain.FilterChainContext"; + private static final String HANDLE_READ = "handleRead"; + @Override public AgentBuilder buildAgentChainedGlobal1(final AgentBuilder builder) { return builder @@ -20,38 +25,35 @@ public AgentBuilder buildAgentChainedGlobal1(final AgentBuilder builder) { .transform(new AgentBuilder.Transformer() { @Override public DynamicType.Builder transform(final DynamicType.Builder builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) { - return builder.visit(advice(typeDescription).to(HandleReadAdvice.class).on(named("handleRead") - .and(takesArgument(0, named("org.glassfish.grizzly.filterchain.FilterChainContext"))) - .and(isPublic()))); + return builder.visit(advice(typeDescription).to(HandleReadAdvice.class).on(named(HANDLE_READ) + .and(takesArgument(0, named(FILTER_CHAIN_CONTEXT))))); } }) .transform(new AgentBuilder.Transformer() { @Override public DynamicType.Builder transform(final DynamicType.Builder builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) { return builder.visit(advice(typeDescription).to(PrepareResponseAdvice.class).on(named("prepareResponse") - .and(takesArgument(0, named("org.glassfish.grizzly.filterchain.FilterChainContext"))) - .and(takesArgument(1, named("org.glassfish.grizzly.http.HttpRequestPacket"))) - .and(takesArgument(2, named("org.glassfish.grizzly.http.HttpResponsePacket"))) - .and(takesArgument(3, named("org.glassfish.grizzly.http.HttpContent"))) - .and(isPrivate()))); + .and(takesArgument(0, named(FILTER_CHAIN_CONTEXT))) + .and(takesArgument(2, named("org.glassfish.grizzly.http.HttpResponsePacket"))))); } }) - .type(hasSuperType(named("org.glassfish.grizzly.filterchain.BaseFilter")) - // common grizzly filters - .and(not(named("org.glassfish.grizzly.filterchain.TransportFilter"))) - .and(not(named("org.glassfish.grizzly.nio.transport.TCPNIOTransportFilter"))) - // TODO: 7/11/20 Figure out why HttpServerFilter still matches - .and(not(named("org.glassfish.grizzly.http.HttpServerFilter"))) - .and(not(named("org.glassfish.grizzly.utils.IdleTimeoutFilter"))) - .and(not(named("org.glassfish.grizzly.http.server.FileCacheFilter"))) - ) + .type(hasSuperClass(named("org.glassfish.grizzly.filterchain.BaseFilter")) + // common http server filters + .and(not(named("org.glassfish.grizzly.filterchain.TransportFilter") + .or(named("org.glassfish.grizzly.nio.transport.TCPNIOTransportFilter")) + .or(named("org.glassfish.grizzly.http.HttpServerFilter")) + .or(named("org.glassfish.grizzly.http.HttpCodecFilter")) + .or(named("org.glassfish.grizzly.utils.IdleTimeoutFilter")) + // common http client filters + .or(named("com.ning.http.client.providers.grizzly.AsyncHttpClientFilter")) + .or(named("org.glassfish.grizzly.websockets.WebSocketClientFilter")) + .or(hasSuperClass(named("org.glassfish.grizzly.http.HttpClientFilter")))))) .transform(new AgentBuilder.Transformer() { @Override public DynamicType.Builder transform(final DynamicType.Builder builder, final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) { - return builder.visit(advice(typeDescription).to(WorkerHandleReadAdvice.class).on(named("handleRead") - .and(takesArgument(0, named("org.glassfish.grizzly.filterchain.FilterChainContext"))) - .and(isPublic()))); + return builder.visit(advice(typeDescription).to(WorkerHandleReadAdvice.class).on(named(HANDLE_READ) + .and(takesArgument(0, named(FILTER_CHAIN_CONTEXT))))); } }); } @@ -77,11 +79,8 @@ public static void onEnter( @Advice.Argument(value = 0, typing = Assigner.Typing.DYNAMIC) final Object ctx, @Advice.Local("scope") Scope scope) { - // manually filtering HttpServerFilter - if (new StringMatcher("org.glassfish.grizzly.http.HttpServerFilter", - StringMatcher.Mode.EQUALS_FULLY).matches(thiz.getClass().getName())) { + if (hackShouldFilter(thiz)) return; - } if (isAllowed(className, origin)) scope = WorkerFilterIntercept.onHandleReadEnter(ctx); @@ -91,7 +90,12 @@ public static void onEnter( public static void onExit( final @ClassName String className, final @Advice.Origin String origin, + final @Advice.This Object thiz, @Advice.Local("scope") Scope scope) { + + if (hackShouldFilter(thiz)) + return; + if (isAllowed(className, origin)) WorkerFilterIntercept.onHandleReadExit(scope); } @@ -104,9 +108,17 @@ public static void onExit( final @Advice.Origin String origin, @Advice.Argument(value = 0, typing = Assigner.Typing.DYNAMIC) final Object ctx, @Advice.Argument(value = 2, typing = Assigner.Typing.DYNAMIC) final Object response) { + if (isAllowed(className, origin)) HttpServerFilterIntercept.onPrepareResponse(ctx, response); } } + + public static boolean hackShouldFilter(Object thiz) { + // TODO: 7/11/20 figure out why these are not filtered at TypeDescription + logger.log(Level.FINER, "Checking predicate for potential worker filter " + thiz.getClass().getName()); + return "com.ning.http.client.providers.grizzly.AsyncHttpClientFilter".equals(thiz.getClass().getName()) || + "org.glassfish.grizzly.websockets.WebSocketClientFilter".equals(thiz.getClass().getName()); + } } diff --git a/rule/grizzly-http-server/src/test/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerTest.java b/rule/grizzly-http-server/src/test/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerTest.java index 39cb716f8..b8e1ac64a 100644 --- a/rule/grizzly-http-server/src/test/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerTest.java +++ b/rule/grizzly-http-server/src/test/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerTest.java @@ -19,8 +19,11 @@ import static org.junit.Assert.*; import java.io.IOException; +import java.net.URL; import java.util.List; +import com.ning.http.client.AsyncHttpClient; +import io.opentracing.contrib.grizzly.http.server.AbstractHttpTest; import org.glassfish.grizzly.http.server.HttpHandler; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.grizzly.http.server.NetworkListener; @@ -39,9 +42,7 @@ * @author Jose Montoya */ @RunWith(AgentRunner.class) -public class HttpServerTest { - protected static final int PORT = 18906; - protected static final String LOCALHOST = "localhost"; +public class HttpServerTest extends AbstractHttpTest { private HttpServer httpServer; @Before @@ -70,9 +71,11 @@ public void service(final Request request, final Response response) throws Excep response.setStatus(201); } }); - - final org.apache.http.client.fluent.Response response = org.apache.http.client.fluent.Request.Get("http://" + LOCALHOST + ":" + PORT + "/").addHeader("beep", "boop").execute(); - assertEquals(201, response.returnResponse().getStatusLine().getStatusCode()); + + try (final AsyncHttpClient client = new AsyncHttpClient()) { + final com.ning.http.client.Response response = client.prepareGet(new URL("http", LOCALHOST, PORT, "/").toString()).execute().get(); + assertEquals(201, response.getStatusCode()); + } final List spans = tracer.finishedSpans(); assertEquals(1, spans.size()); From d3bfd68357f3f1874d565ff832fd395146b095b0 Mon Sep 17 00:00:00 2001 From: Jose Montoya Date: Sun, 12 Jul 2020 00:04:00 -0500 Subject: [PATCH 7/7] grizzly-http-server: minor cleanup --- .../GizzlyHttpRequestPacketAdapter.java | 47 ------------------- .../server/HttpServerFilterIntercept.java | 2 +- .../http/server/WorkerFilterIntercept.java | 11 ----- 3 files changed, 1 insertion(+), 59 deletions(-) delete mode 100644 rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/GizzlyHttpRequestPacketAdapter.java diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/GizzlyHttpRequestPacketAdapter.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/GizzlyHttpRequestPacketAdapter.java deleted file mode 100644 index 1a9e6bbbd..000000000 --- a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/GizzlyHttpRequestPacketAdapter.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2018 The OpenTracing Authors - * - * 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.opentracing.contrib.specialagent.rule.grizzly.http.server; - -import io.opentracing.propagation.TextMap; -import org.glassfish.grizzly.http.HttpRequestPacket; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -/** - * @author Jose Montoya - */ -public class GizzlyHttpRequestPacketAdapter implements TextMap { - private final HttpRequestPacket requestPacket; - private final Map headers; - - public GizzlyHttpRequestPacketAdapter(HttpRequestPacket requestPacket) { - this.requestPacket = requestPacket; - this.headers = new HashMap<>(requestPacket.getHeaders().size()); - for (String headerName : requestPacket.getHeaders().names()) { - headers.put(headerName, requestPacket.getHeaders().getHeader(headerName)); - } - } - - @Override - public Iterator> iterator() { - return headers.entrySet().iterator(); - } - - @Override - public void put(String key, String value) { - requestPacket.addHeader(key, value); - } -} diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java index ddee00aa8..794a62658 100644 --- a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/HttpServerFilterIntercept.java @@ -3,10 +3,10 @@ import io.opentracing.Span; import io.opentracing.SpanContext; import io.opentracing.Tracer; +import io.opentracing.contrib.grizzly.http.server.GizzlyHttpRequestPacketAdapter; import io.opentracing.contrib.grizzly.http.server.GrizzlyServerSpanDecorator; import io.opentracing.propagation.Format; import io.opentracing.propagation.TextMap; -import io.opentracing.tag.Tags; import io.opentracing.util.GlobalTracer; import org.glassfish.grizzly.filterchain.FilterChainContext; import org.glassfish.grizzly.filterchain.NextAction; diff --git a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/WorkerFilterIntercept.java b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/WorkerFilterIntercept.java index 096b1333c..618caa43a 100644 --- a/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/WorkerFilterIntercept.java +++ b/rule/grizzly-http-server/src/main/java/io/opentracing/contrib/specialagent/rule/grizzly/http/server/WorkerFilterIntercept.java @@ -2,18 +2,7 @@ import io.opentracing.Scope; import io.opentracing.Span; -import io.opentracing.SpanContext; -import io.opentracing.Tracer; -import io.opentracing.propagation.Format; -import io.opentracing.propagation.TextMap; -import io.opentracing.tag.Tags; import io.opentracing.util.GlobalTracer; -import org.glassfish.grizzly.filterchain.FilterChainContext; -import org.glassfish.grizzly.filterchain.NextAction; -import org.glassfish.grizzly.http.HttpContent; -import org.glassfish.grizzly.http.HttpHeader; -import org.glassfish.grizzly.http.HttpRequestPacket; -import org.glassfish.grizzly.http.HttpResponsePacket; public class WorkerFilterIntercept { public static Scope onHandleReadEnter(