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 0000000000..a9380503da --- /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 5ce1a32a79..f38aa9b129 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,10 @@ public final class ArmeriaSingletons { .build(); CLIENT_DECORATOR = telemetry.newClientDecorator(); - SERVER_DECORATOR = telemetry.newServiceDecorator(); + 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/ResponseCustomizingDecorator.java b/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ResponseCustomizingDecorator.java new file mode 100644 index 0000000000..35a60207e8 --- /dev/null +++ b/instrumentation/armeria-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/armeria/v1_3/ResponseCustomizingDecorator.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 ResponseCustomizingDecorator extends SimpleDecoratingHttpService { + + ResponseCustomizingDecorator(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 a06475ed84..15ba43dda4 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 com.linecorp.armeria.server.ServerBuilder; 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 acddb93f8e..7c684f4e80 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 @@ public abstract class AbstractArmeriaHttpServerTest extends AbstractHttpServerTe } @Override - protected final void configure(HttpServerTestOptions options) { + protected void configure(HttpServerTestOptions options) { options.setExpectedHttpRoute( endpoint -> { if (endpoint == ServerEndpoint.NOT_FOUND) {