From c73bf8eadf84ec89991640fb3680bea7b0d693e5 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 29 Feb 2024 04:08:07 +0100 Subject: [PATCH] Fix native tests (#10685) Co-authored-by: Jean Bisutti Co-authored-by: Trask Stalnaker Co-authored-by: Lauri Tulmin --- .../build.gradle.kts | 1 - .../OtelResourceAutoConfiguration.java | 20 +---- .../resources/SpringResourceProvider.java | 17 +++++ .../OpenTelemetryAutoConfigurationTest.java | 50 ------------- .../resources/SpringResourceProviderTest.java | 75 +++++++++++++++++++ .../SpringBootServiceNameDetector.java | 4 +- .../SpringBootServiceVersionDetector.java | 4 + .../spring-boot-starter/build.gradle.kts | 1 - .../OtelSpringStarterDisabledSmokeTest.java | 4 + 9 files changed, 106 insertions(+), 70 deletions(-) diff --git a/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts b/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts index 980e1376f470..ffe05a2e8c9b 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts +++ b/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts @@ -46,7 +46,6 @@ dependencies { compileOnly(project(":instrumentation-annotations")) compileOnly(project(":instrumentation:resources:library")) - compileOnly(project(":instrumentation:spring:spring-boot-resources:library")) annotationProcessor("com.google.auto.service:auto-service") compileOnly("com.google.auto.service:auto-service-annotations") diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/OtelResourceAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/OtelResourceAutoConfiguration.java index 2efcf96bb327..dd732636334a 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/OtelResourceAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/OtelResourceAutoConfiguration.java @@ -17,14 +17,14 @@ import io.opentelemetry.instrumentation.resources.ProcessRuntimeResourceProvider; import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled; -import io.opentelemetry.instrumentation.spring.resources.SpringBootServiceNameDetector; -import io.opentelemetry.instrumentation.spring.resources.SpringBootServiceVersionDetector; import io.opentelemetry.sdk.autoconfigure.internal.EnvironmentResourceProvider; import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; +import java.util.Optional; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.info.BuildProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @@ -42,8 +42,8 @@ public ResourceProvider otelEnvironmentResourceProvider() { } @Bean - public ResourceProvider otelSpringResourceProvider() { - return new SpringResourceProvider(); + public ResourceProvider otelSpringResourceProvider(Optional buildProperties) { + return new SpringResourceProvider(buildProperties); } @Bean @@ -51,18 +51,6 @@ public ResourceProvider otelDistroVersionResourceProvider() { return new DistroVersionResourceProvider(); } - @Bean - @ConditionalOnClass(SpringBootServiceNameDetector.class) - public ResourceProvider otelSpringBootServiceNameResourceProvider() { - return new SpringBootServiceNameDetector(); - } - - @Bean - @ConditionalOnClass(SpringBootServiceVersionDetector.class) - public ResourceProvider otelSpringBootServiceVersionResourceProvider() { - return new SpringBootServiceVersionDetector(); - } - @Bean @ConditionalOnClass(OsResource.class) public ResourceProvider otelOsResourceProvider() { diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProvider.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProvider.java index 756d227f818e..baf76a586ce2 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProvider.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProvider.java @@ -11,16 +11,33 @@ import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.semconv.ResourceAttributes; +import java.util.Optional; +import org.springframework.boot.info.BuildProperties; public class SpringResourceProvider implements ResourceProvider { + private final Optional buildProperties; + + public SpringResourceProvider(Optional buildProperties) { + this.buildProperties = buildProperties; + } + @Override public Resource createResource(ConfigProperties configProperties) { AttributesBuilder attributesBuilder = Attributes.builder(); + buildProperties + .map(BuildProperties::getName) + .ifPresent(v -> attributesBuilder.put(ResourceAttributes.SERVICE_NAME, v)); + String springApplicationName = configProperties.getString("spring.application.name"); if (springApplicationName != null) { attributesBuilder.put(ResourceAttributes.SERVICE_NAME, springApplicationName); } + + buildProperties + .map(BuildProperties::getVersion) + .ifPresent(v -> attributesBuilder.put(ResourceAttributes.SERVICE_VERSION, v)); + return Resource.create(attributesBuilder.build()); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfigurationTest.java index e0bf3f98f849..90a750292c03 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfigurationTest.java @@ -5,7 +5,6 @@ package io.opentelemetry.instrumentation.spring.autoconfigure; -import static io.opentelemetry.semconv.ResourceAttributes.SERVICE_NAME; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; @@ -100,55 +99,6 @@ void initializeOpenTelemetryWithCustomProviders() { .doesNotHaveBean("sdkLoggerProvider")); } - @Test - @DisplayName( - "when spring.application.name is set value should be passed to service name attribute") - void shouldDetermineServiceNameBySpringApplicationName() { - this.contextRunner - .withPropertyValues("spring.application.name=myapp-backend") - .withConfiguration( - AutoConfigurations.of( - OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class)) - .run( - context -> { - Resource otelResource = context.getBean("otelResource", Resource.class); - - assertThat(otelResource.getAttribute(SERVICE_NAME)).isEqualTo("myapp-backend"); - }); - } - - @Test - @DisplayName( - "when spring application name and otel service name are not set service name should be default") - void hasDefaultServiceName() { - this.contextRunner - .withConfiguration( - AutoConfigurations.of( - OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class)) - .run( - context -> { - Resource otelResource = context.getBean("otelResource", Resource.class); - - assertThat(otelResource.getAttribute(SERVICE_NAME)).isEqualTo("unknown_service:java"); - }); - } - - @Test - @DisplayName("when otel service name is set it should be set as service name attribute") - void shouldDetermineServiceNameByOtelServiceName() { - this.contextRunner - .withConfiguration( - AutoConfigurations.of( - OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class)) - .withPropertyValues("otel.resource.attributes.service.name=otel-name-backend") - .run( - context -> { - Resource otelResource = context.getBean("otelResource", Resource.class); - - assertThat(otelResource.getAttribute(SERVICE_NAME)).isEqualTo("otel-name-backend"); - }); - } - @Test @DisplayName("when otel attributes are set in properties they should be put in resource") void shouldInitializeAttributes() { diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProviderTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProviderTest.java index e896b0a96123..cfe3da4d171e 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProviderTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProviderTest.java @@ -5,6 +5,8 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.resources; +import static io.opentelemetry.semconv.ResourceAttributes.SERVICE_NAME; +import static io.opentelemetry.semconv.ResourceAttributes.SERVICE_VERSION; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; @@ -13,9 +15,12 @@ import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.resources.Resource; +import java.util.Properties; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.info.BuildProperties; import org.springframework.boot.test.context.runner.ApplicationContextRunner; public class SpringResourceProviderTest { @@ -54,4 +59,74 @@ void hasDefaultTypes() { context -> assertThat(context.getBean(OtelResourceProperties.class).getAttributes()).isEmpty()); } + + @Test + @DisplayName( + "when spring.application.name is set value should be passed to service name attribute") + void shouldDetermineServiceNameBySpringApplicationName() { + this.contextRunner + .withPropertyValues("spring.application.name=myapp-backend") + .withConfiguration( + AutoConfigurations.of( + OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class)) + .run( + context -> { + Resource otelResource = context.getBean("otelResource", Resource.class); + + assertThat(otelResource.getAttribute(SERVICE_NAME)).isEqualTo("myapp-backend"); + }); + } + + @Test + @DisplayName( + "when spring.application.name is set value should be passed to service name attribute") + void shouldDetermineServiceNameAndVersionBySpringApplicationVersion() { + Properties properties = new Properties(); + properties.put("name", "demo"); + properties.put("version", "0.3"); + this.contextRunner + .withBean("buildProperties", BuildProperties.class, () -> new BuildProperties(properties)) + .withConfiguration( + AutoConfigurations.of( + OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class)) + .run( + context -> { + Resource otelResource = context.getBean("otelResource", Resource.class); + + assertThat(otelResource.getAttribute(SERVICE_NAME)).isEqualTo("demo"); + assertThat(otelResource.getAttribute(SERVICE_VERSION)).isEqualTo("0.3"); + }); + } + + @Test + @DisplayName( + "when spring application name and otel service name are not set service name should be default") + void hasDefaultServiceName() { + this.contextRunner + .withConfiguration( + AutoConfigurations.of( + OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class)) + .run( + context -> { + Resource otelResource = context.getBean("otelResource", Resource.class); + + assertThat(otelResource.getAttribute(SERVICE_NAME)).isEqualTo("unknown_service:java"); + }); + } + + @Test + @DisplayName("when otel service name is set it should be set as service name attribute") + void shouldDetermineServiceNameByOtelServiceName() { + this.contextRunner + .withConfiguration( + AutoConfigurations.of( + OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class)) + .withPropertyValues("otel.resource.attributes.service.name=otel-name-backend") + .run( + context -> { + Resource otelResource = context.getBean("otelResource", Resource.class); + + assertThat(otelResource.getAttribute(SERVICE_NAME)).isEqualTo("otel-name-backend"); + }); + } } diff --git a/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameDetector.java b/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameDetector.java index 02eb3897ba3c..6ec01260aeaa 100644 --- a/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameDetector.java +++ b/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameDetector.java @@ -46,8 +46,8 @@ *
  • Check for --spring.application.name program argument via sun.java.command system property * * - *

    Note: should not be used inside a spring application, where the spring.application.name is - * already available. + *

    Note: The spring starter already includes provider in + * io.opentelemetry.instrumentation.spring.autoconfigure.resources.SpringResourceProvider */ @AutoService(ResourceProvider.class) public class SpringBootServiceNameDetector implements ConditionalResourceProvider { diff --git a/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceVersionDetector.java b/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceVersionDetector.java index 3c9ddb05fcdd..b858e28e8acd 100644 --- a/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceVersionDetector.java +++ b/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceVersionDetector.java @@ -18,6 +18,10 @@ import java.util.Properties; import java.util.logging.Logger; +/** + * Note: The spring starter already includes provider in + * io.opentelemetry.instrumentation.spring.autoconfigure.resources.SpringResourceProvider + */ @AutoService(ResourceProvider.class) public class SpringBootServiceVersionDetector implements ResourceProvider { diff --git a/instrumentation/spring/starters/spring-boot-starter/build.gradle.kts b/instrumentation/spring/starters/spring-boot-starter/build.gradle.kts index 600b789300c0..66e481b2e6e6 100644 --- a/instrumentation/spring/starters/spring-boot-starter/build.gradle.kts +++ b/instrumentation/spring/starters/spring-boot-starter/build.gradle.kts @@ -14,7 +14,6 @@ dependencies { api(project(":instrumentation:spring:spring-boot-autoconfigure")) api(project(":instrumentation-annotations")) implementation(project(":instrumentation:resources:library")) - implementation(project(":instrumentation:spring:spring-boot-resources:library")) api("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi") api("io.opentelemetry:opentelemetry-api") api("io.opentelemetry:opentelemetry-exporter-logging") diff --git a/smoke-tests-otel-starter/src/test/java/io/opentelemetry/smoketest/OtelSpringStarterDisabledSmokeTest.java b/smoke-tests-otel-starter/src/test/java/io/opentelemetry/smoketest/OtelSpringStarterDisabledSmokeTest.java index d6485fab5a50..212b485bbc6f 100644 --- a/smoke-tests-otel-starter/src/test/java/io/opentelemetry/smoketest/OtelSpringStarterDisabledSmokeTest.java +++ b/smoke-tests-otel-starter/src/test/java/io/opentelemetry/smoketest/OtelSpringStarterDisabledSmokeTest.java @@ -7,6 +7,7 @@ import io.opentelemetry.spring.smoketest.OtelSpringStarterSmokeTestApplication; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledInNativeImage; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest( @@ -15,6 +16,9 @@ OtelSpringStarterSmokeTest.TestConfiguration.class }, properties = {"otel.sdk.disabled=true"}) +@DisabledInNativeImage // Without this the native tests in the OtelSpringStarterSmokeTest class will +// fail with org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "TEST_TABLE" +// already exists class OtelSpringStarterDisabledSmokeTest { @Test