|
@@ -0,0 +1,179 @@
|
|
|
+/*
|
|
|
+ * Copyright The OpenTelemetry Authors
|
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
|
+ */
|
|
|
+
|
|
|
+package io.opentelemetry.javaagent.instrumentation.spring.ws.v2_0;
|
|
|
+
|
|
|
+import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
|
|
|
+import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
|
|
|
+import static io.opentelemetry.semconv.ExceptionAttributes.EXCEPTION_MESSAGE;
|
|
|
+import static io.opentelemetry.semconv.ExceptionAttributes.EXCEPTION_STACKTRACE;
|
|
|
+import static io.opentelemetry.semconv.ExceptionAttributes.EXCEPTION_TYPE;
|
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
|
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
|
+
|
|
|
+import com.google.common.collect.ImmutableMap;
|
|
|
+import io.opentelemetry.api.trace.SpanKind;
|
|
|
+import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
|
|
|
+import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerUsingTest;
|
|
|
+import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension;
|
|
|
+import io.opentelemetry.sdk.trace.data.StatusData;
|
|
|
+import io.opentelemetry.semconv.incubating.CodeIncubatingAttributes;
|
|
|
+import io.opentelemetry.test.hello_web_service.HelloRequest;
|
|
|
+import io.opentelemetry.test.hello_web_service.HelloRequestSoapAction;
|
|
|
+import io.opentelemetry.test.hello_web_service.HelloRequestWsAction;
|
|
|
+import io.opentelemetry.test.hello_web_service.HelloResponse;
|
|
|
+import java.net.URISyntaxException;
|
|
|
+import org.junit.jupiter.api.AfterAll;
|
|
|
+import org.junit.jupiter.api.BeforeAll;
|
|
|
+import org.junit.jupiter.api.extension.RegisterExtension;
|
|
|
+import org.junit.jupiter.params.ParameterizedTest;
|
|
|
+import org.junit.jupiter.params.provider.ValueSource;
|
|
|
+import org.springframework.boot.SpringApplication;
|
|
|
+import org.springframework.context.ConfigurableApplicationContext;
|
|
|
+import org.springframework.oxm.jaxb.Jaxb2Marshaller;
|
|
|
+import org.springframework.util.ClassUtils;
|
|
|
+import org.springframework.ws.client.core.WebServiceMessageCallback;
|
|
|
+import org.springframework.ws.client.core.WebServiceTemplate;
|
|
|
+import org.springframework.ws.soap.addressing.client.ActionCallback;
|
|
|
+import org.springframework.ws.soap.client.SoapFaultClientException;
|
|
|
+import org.springframework.ws.soap.client.core.SoapActionCallback;
|
|
|
+
|
|
|
+class SpringWsTest extends AbstractHttpServerUsingTest<ConfigurableApplicationContext> {
|
|
|
+
|
|
|
+ @RegisterExtension
|
|
|
+ private static final InstrumentationExtension testing =
|
|
|
+ HttpServerInstrumentationExtension.forAgent();
|
|
|
+
|
|
|
+ private static final Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
|
|
|
+
|
|
|
+ @BeforeAll
|
|
|
+ void setup() {
|
|
|
+ startServer();
|
|
|
+ }
|
|
|
+
|
|
|
+ @AfterAll
|
|
|
+ void cleanup() {
|
|
|
+ cleanupServer();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected ConfigurableApplicationContext setupServer() throws Exception {
|
|
|
+ SpringApplication app = new SpringApplication(AppConfig.class, WebServiceConfig.class);
|
|
|
+ app.setDefaultProperties(
|
|
|
+ ImmutableMap.of(
|
|
|
+ "server.port",
|
|
|
+ port,
|
|
|
+ "server.context-path",
|
|
|
+ getContextPath(),
|
|
|
+ "server.servlet.contextPath",
|
|
|
+ getContextPath(),
|
|
|
+ "server.error.include-message",
|
|
|
+ "always"));
|
|
|
+ marshaller.setPackagesToScan(ClassUtils.getPackageName(HelloRequest.class));
|
|
|
+ marshaller.afterPropertiesSet();
|
|
|
+ return app.run();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void stopServer(ConfigurableApplicationContext configurableApplicationContext)
|
|
|
+ throws Exception {
|
|
|
+ configurableApplicationContext.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected String getContextPath() {
|
|
|
+ return "/xyz";
|
|
|
+ }
|
|
|
+
|
|
|
+ HelloResponse makeRequest(String methodName, String name) throws URISyntaxException {
|
|
|
+ WebServiceTemplate webServiceTemplate = new WebServiceTemplate(marshaller);
|
|
|
+
|
|
|
+ Object request;
|
|
|
+ WebServiceMessageCallback callback = null;
|
|
|
+ if ("hello".equals(methodName)) {
|
|
|
+ HelloRequest req = new HelloRequest();
|
|
|
+ req.setName(name);
|
|
|
+ request = req;
|
|
|
+ } else if ("helloSoapAction".equals(methodName)) {
|
|
|
+ HelloRequestSoapAction req = new HelloRequestSoapAction();
|
|
|
+ req.setName(name);
|
|
|
+ request = req;
|
|
|
+ callback = new SoapActionCallback("http://opentelemetry.io/test/hello-soap-action");
|
|
|
+ } else if ("helloWsAction".equals(methodName)) {
|
|
|
+ HelloRequestWsAction req = new HelloRequestWsAction();
|
|
|
+ req.setName(name);
|
|
|
+ request = req;
|
|
|
+ callback = new ActionCallback("http://opentelemetry.io/test/hello-ws-action");
|
|
|
+ } else {
|
|
|
+ throw new IllegalArgumentException(methodName);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (HelloResponse)
|
|
|
+ webServiceTemplate.marshalSendAndReceive(
|
|
|
+ address.resolve("ws").toString(), request, callback);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ParameterizedTest
|
|
|
+ @ValueSource(strings = {"hello", "helloSoapAction", "helloWsAction"})
|
|
|
+ void testMethodName(String methodName) throws URISyntaxException {
|
|
|
+ HelloResponse response = makeRequest(methodName, "Test");
|
|
|
+
|
|
|
+ assertThat(response.getMessage()).isEqualTo("Hello Test");
|
|
|
+
|
|
|
+ testing.waitAndAssertTraces(
|
|
|
+ trace ->
|
|
|
+ trace.hasSpansSatisfyingExactly(
|
|
|
+ span -> span.hasNoParent().hasName("POST /xyz/ws/*").hasKind(SpanKind.SERVER),
|
|
|
+ span ->
|
|
|
+ span.hasParent(trace.getSpan(0))
|
|
|
+ .hasName("HelloEndpoint." + methodName)
|
|
|
+ .hasKind(SpanKind.INTERNAL)
|
|
|
+ .hasAttributesSatisfyingExactly(
|
|
|
+ equalTo(
|
|
|
+ CodeIncubatingAttributes.CODE_NAMESPACE,
|
|
|
+ "io.opentelemetry.javaagent.instrumentation.spring.ws.v2_0.HelloEndpoint"),
|
|
|
+ equalTo(CodeIncubatingAttributes.CODE_FUNCTION, methodName))));
|
|
|
+ }
|
|
|
+
|
|
|
+ @ParameterizedTest
|
|
|
+ @ValueSource(strings = {"hello", "helloSoapAction", "helloWsAction"})
|
|
|
+ void testMethodNameException(String methodName) {
|
|
|
+ assertThatThrownBy(() -> makeRequest(methodName, "exception"))
|
|
|
+ .isInstanceOf(SoapFaultClientException.class)
|
|
|
+ .hasMessage("hello exception");
|
|
|
+
|
|
|
+ Exception expectedException = new Exception("hello exception");
|
|
|
+ testing.waitAndAssertTraces(
|
|
|
+ trace ->
|
|
|
+ trace.hasSpansSatisfyingExactly(
|
|
|
+ span ->
|
|
|
+ span.hasNoParent()
|
|
|
+ .hasName("POST /xyz/ws/*")
|
|
|
+ .hasKind(SpanKind.SERVER)
|
|
|
+ .hasStatus(StatusData.error()),
|
|
|
+ span ->
|
|
|
+ span.hasParent(trace.getSpan(0))
|
|
|
+ .hasName("HelloEndpoint." + methodName)
|
|
|
+ .hasKind(SpanKind.INTERNAL)
|
|
|
+ .hasStatus(StatusData.error())
|
|
|
+ .hasEventsSatisfyingExactly(
|
|
|
+ event ->
|
|
|
+ event
|
|
|
+ .hasName("exception")
|
|
|
+ .hasAttributesSatisfyingExactly(
|
|
|
+ equalTo(
|
|
|
+ EXCEPTION_TYPE,
|
|
|
+ expectedException.getClass().getCanonicalName()),
|
|
|
+ equalTo(EXCEPTION_MESSAGE, expectedException.getMessage()),
|
|
|
+ satisfies(
|
|
|
+ EXCEPTION_STACKTRACE,
|
|
|
+ val -> val.isInstanceOf(String.class))))
|
|
|
+ .hasAttributesSatisfyingExactly(
|
|
|
+ equalTo(
|
|
|
+ CodeIncubatingAttributes.CODE_NAMESPACE,
|
|
|
+ "io.opentelemetry.javaagent.instrumentation.spring.ws.v2_0.HelloEndpoint"),
|
|
|
+ equalTo(CodeIncubatingAttributes.CODE_FUNCTION, methodName))));
|
|
|
+ }
|
|
|
+}
|