From ebb133a480f3d51122d28bf1a301f2f054d026b4 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 11 Apr 2023 19:46:52 +0300 Subject: [PATCH 1/2] Implement HttpServerResponseCustomizer support for Armeria --- .../v1_3/ArmeriaHttpResponseMutator.java | 18 +++++++ .../armeria/v1_3/ArmeriaSingletons.java | 7 ++- .../v1_3/ResponseCustomizerDecorator.java | 47 +++++++++++++++++++ .../armeria/v1_3/ArmeriaHttpServerTest.java | 9 ++++ .../v1_3/AbstractArmeriaHttpServerTest.java | 2 +- 5 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaHttpResponseMutator.java create mode 100644 instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ResponseCustomizerDecorator.java diff --git a/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaHttpResponseMutator.java b/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaHttpResponseMutator.java new file mode 100644 index 000000000000..a9380503da0a --- /dev/null +++ b/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaHttpResponseMutator.java @@ -0,0 +1,18 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.armeria.v1_3; + +import com.linecorp.armeria.common.ResponseHeadersBuilder; +import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseMutator; + +enum ArmeriaHttpResponseMutator implements HttpServerResponseMutator { + INSTANCE; + + @Override + public void appendHeader(ResponseHeadersBuilder response, String name, String value) { + response.add(name, value); + } +} diff --git a/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaSingletons.java b/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaSingletons.java index 5ce1a32a79f2..eb7ee974ba55 100644 --- a/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaSingletons.java +++ b/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaSingletons.java @@ -35,7 +35,12 @@ public final class ArmeriaSingletons { .build(); CLIENT_DECORATOR = telemetry.newClientDecorator(); - SERVER_DECORATOR = telemetry.newServiceDecorator(); + SERVER_DECORATOR = wrapResponseCustomizer(telemetry.newServiceDecorator()); + } + + private static Function wrapResponseCustomizer( + Function function) { + return function.compose(service -> new ResponseCustomizerDecorator(service)); } private ArmeriaSingletons() {} diff --git a/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ResponseCustomizerDecorator.java b/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ResponseCustomizerDecorator.java new file mode 100644 index 000000000000..7cfedd85d9b8 --- /dev/null +++ b/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ResponseCustomizerDecorator.java @@ -0,0 +1,47 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.armeria.v1_3; + +import com.linecorp.armeria.common.FilteredHttpResponse; +import com.linecorp.armeria.common.HttpObject; +import com.linecorp.armeria.common.HttpRequest; +import com.linecorp.armeria.common.HttpResponse; +import com.linecorp.armeria.common.ResponseHeaders; +import com.linecorp.armeria.common.ResponseHeadersBuilder; +import com.linecorp.armeria.server.HttpService; +import com.linecorp.armeria.server.ServiceRequestContext; +import com.linecorp.armeria.server.SimpleDecoratingHttpService; +import io.opentelemetry.context.Context; +import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizerHolder; + +class ResponseCustomizerDecorator extends SimpleDecoratingHttpService { + + ResponseCustomizerDecorator(HttpService delegate) { + super(delegate); + } + + @Override + public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception { + HttpResponse response = unwrap().serve(ctx, req); + Context context = Context.current(); + return new FilteredHttpResponse(response) { + @Override + public HttpObject filter(HttpObject obj) { + // Ignore other objects like HttpData. + if (!(obj instanceof ResponseHeaders)) { + return obj; + } + + ResponseHeaders headers = (ResponseHeaders) obj; + ResponseHeadersBuilder headersBuilder = headers.toBuilder(); + HttpServerResponseCustomizerHolder.getCustomizer() + .customize(context, headersBuilder, ArmeriaHttpResponseMutator.INSTANCE); + + return headersBuilder.build(); + } + }; + } +} diff --git a/instrumentation/armeria-1.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaHttpServerTest.java b/instrumentation/armeria-1.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaHttpServerTest.java index a06475ed844f..15ba43dda47a 100644 --- a/instrumentation/armeria-1.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaHttpServerTest.java +++ b/instrumentation/armeria-1.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaHttpServerTest.java @@ -9,6 +9,8 @@ import io.opentelemetry.instrumentation.armeria.v1_3.AbstractArmeriaHttpServerTest; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.http.HttpServerTestOptions; +import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint; import org.junit.jupiter.api.extension.RegisterExtension; class ArmeriaHttpServerTest extends AbstractArmeriaHttpServerTest { @@ -20,4 +22,11 @@ class ArmeriaHttpServerTest extends AbstractArmeriaHttpServerTest { protected ServerBuilder configureServer(ServerBuilder sb) { return sb; } + + @Override + protected void configure(HttpServerTestOptions options) { + super.configure(options); + options.setHasResponseCustomizer( + endpoint -> ServerEndpoint.NOT_FOUND != endpoint && ServerEndpoint.EXCEPTION != endpoint); + } } diff --git a/instrumentation/armeria-1.3/testing/src/main/java/io/opentelemetry/instrumentation/armeria/v1_3/AbstractArmeriaHttpServerTest.java b/instrumentation/armeria-1.3/testing/src/main/java/io/opentelemetry/instrumentation/armeria/v1_3/AbstractArmeriaHttpServerTest.java index acddb93f8e9a..7c684f4e8040 100644 --- a/instrumentation/armeria-1.3/testing/src/main/java/io/opentelemetry/instrumentation/armeria/v1_3/AbstractArmeriaHttpServerTest.java +++ b/instrumentation/armeria-1.3/testing/src/main/java/io/opentelemetry/instrumentation/armeria/v1_3/AbstractArmeriaHttpServerTest.java @@ -176,7 +176,7 @@ protected void stopServer(Server server) { } @Override - protected final void configure(HttpServerTestOptions options) { + protected void configure(HttpServerTestOptions options) { options.setExpectedHttpRoute( endpoint -> { if (endpoint == ServerEndpoint.NOT_FOUND) { From 36ffd6b1befddcca3d673de9fad2fac83c6c44b0 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 11 Apr 2023 21:51:03 +0300 Subject: [PATCH 2/2] address review comments --- .../armeria/v1_3/ArmeriaSingletons.java | 10 ++++------ ...ecorator.java => ResponseCustomizingDecorator.java} | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) rename instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/{ResponseCustomizerDecorator.java => ResponseCustomizingDecorator.java} (92%) diff --git a/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaSingletons.java b/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaSingletons.java index eb7ee974ba55..f38aa9b12941 100644 --- a/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaSingletons.java +++ b/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ArmeriaSingletons.java @@ -35,12 +35,10 @@ public final class ArmeriaSingletons { .build(); CLIENT_DECORATOR = telemetry.newClientDecorator(); - SERVER_DECORATOR = wrapResponseCustomizer(telemetry.newServiceDecorator()); - } - - private static Function wrapResponseCustomizer( - Function function) { - return function.compose(service -> new ResponseCustomizerDecorator(service)); + SERVER_DECORATOR = + telemetry + .newServiceDecorator() + .compose(service -> new ResponseCustomizingDecorator(service)); } private ArmeriaSingletons() {} diff --git a/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ResponseCustomizerDecorator.java b/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ResponseCustomizingDecorator.java similarity index 92% rename from instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ResponseCustomizerDecorator.java rename to instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ResponseCustomizingDecorator.java index 7cfedd85d9b8..35a60207e89e 100644 --- a/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ResponseCustomizerDecorator.java +++ b/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ResponseCustomizingDecorator.java @@ -17,9 +17,9 @@ import io.opentelemetry.context.Context; import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizerHolder; -class ResponseCustomizerDecorator extends SimpleDecoratingHttpService { +class ResponseCustomizingDecorator extends SimpleDecoratingHttpService { - ResponseCustomizerDecorator(HttpService delegate) { + ResponseCustomizingDecorator(HttpService delegate) { super(delegate); }