Skip to content

Commit

Permalink
Fix spring boot 3 webmvc autoconfiguration (#8051)
Browse files Browse the repository at this point in the history
Related to
#8028 (comment)
spring boot 3 uses `jakarta.servlet` so we need to use
`WebMvcFilterAutoConfigurationSpring6 ` instead of
`WebMvcFilterAutoConfiguration`
  • Loading branch information
laurit authored Mar 14, 2023
1 parent 9ebfe03 commit 2cbfec8
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 14 deletions.
31 changes: 20 additions & 11 deletions instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ dependencies {
implementation(project(":instrumentation:spring:spring-web:spring-web-3.1:library"))
implementation(project(":instrumentation:spring:spring-webmvc:spring-webmvc-5.3:library"))
implementation(project(":instrumentation:spring:spring-webmvc:spring-webmvc-6.0:library"))
compileOnly("javax.servlet:javax.servlet-api:3.1.0")
compileOnly("jakarta.servlet:jakarta.servlet-api:5.0.0")
implementation(project(":instrumentation:spring:spring-webflux:spring-webflux-5.3:library"))
implementation(project(":instrumentation:micrometer:micrometer-1.5:library"))

compileOnly("org.springframework.kafka:spring-kafka:2.9.0")
compileOnly("org.springframework.boot:spring-boot-starter-actuator:$springBootVersion")
compileOnly("org.springframework.boot:spring-boot-starter-aop:$springBootVersion")
compileOnly("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
compileOnly("org.springframework.boot:spring-boot-starter-webflux:$springBootVersion")
library("org.springframework.kafka:spring-kafka:2.9.0")
library("org.springframework.boot:spring-boot-starter-actuator:$springBootVersion")
library("org.springframework.boot:spring-boot-starter-aop:$springBootVersion")
library("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
library("org.springframework.boot:spring-boot-starter-webflux:$springBootVersion")

compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi")
compileOnly("io.opentelemetry:opentelemetry-extension-annotations")
Expand All @@ -44,15 +45,12 @@ dependencies {
annotationProcessor("com.google.auto.service:auto-service")
compileOnly("com.google.auto.service:auto-service-annotations")

testImplementation("org.springframework.kafka:spring-kafka:2.9.0")
testImplementation("org.springframework.boot:spring-boot-starter-actuator:$springBootVersion")
testImplementation("org.springframework.boot:spring-boot-starter-aop:$springBootVersion")
testImplementation("org.springframework.boot:spring-boot-starter-webflux:$springBootVersion")
testImplementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
testImplementation("org.springframework.boot:spring-boot-starter-test:$springBootVersion") {
testLibrary("org.springframework.boot:spring-boot-starter-test:$springBootVersion") {
exclude("org.junit.vintage", "junit-vintage-engine")
}
testImplementation("org.testcontainers:kafka")
testImplementation("javax.servlet:javax.servlet-api:3.1.0")
testImplementation("jakarta.servlet:jakarta.servlet-api:5.0.0")

testImplementation(project(":testing-common"))
testImplementation("io.opentelemetry:opentelemetry-sdk")
Expand All @@ -69,11 +67,22 @@ dependencies {
testImplementation(project(":instrumentation-annotations"))
}

val latestDepTest = findProperty("testLatestDeps") as Boolean

// spring 6 (spring boot 3) requires java 17
if (latestDepTest) {
otelJava {
minJavaVersionSupported.set(JavaVersion.VERSION_17)
}
}

tasks.compileTestJava {
options.compilerArgs.add("-parameters")
}

tasks.withType<Test>().configureEach {
systemProperty("testLatestDeps", latestDepTest)

// required on jdk17
jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED")
jvmArgs("-XX:+IgnoreUnrecognizedVMOptions")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ io.opentelemetry.instrumentation.spring.autoconfigure.kafka.KafkaInstrumentation
io.opentelemetry.instrumentation.spring.autoconfigure.metrics.MicrometerShimAutoConfiguration
io.opentelemetry.instrumentation.spring.autoconfigure.propagators.PropagationAutoConfiguration
io.opentelemetry.instrumentation.spring.autoconfigure.resources.OtelResourceAutoConfiguration
io.opentelemetry.instrumentation.spring.autoconfigure.webmvc.WebMvcFilterAutoConfiguration
io.opentelemetry.instrumentation.spring.autoconfigure.webmvc.WebMvcFilterAutoConfigurationSpring6
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ void shouldInstrumentProducerAndConsumer() {
contextRunner.run(KafkaIntegrationTest::runShouldInstrumentProducerAndConsumer);
}

@SuppressWarnings("unchecked")
// In kafka 2 ops.send is deprecated. We are using it to avoid reflection because kafka 3 also has
// ops.send, although with different return type.
@SuppressWarnings({"unchecked", "deprecation"})
private static void runShouldInstrumentProducerAndConsumer(
ConfigurableApplicationContext applicationContext) {
KafkaTemplate<String, String> kafkaTemplate = applicationContext.getBean(KafkaTemplate.class);
Expand All @@ -91,7 +93,7 @@ private static void runShouldInstrumentProducerAndConsumer(
() -> {
kafkaTemplate.executeInTransaction(
ops -> {
ops.usingCompletableFuture().send("testTopic", "10", "testSpan");
ops.send("testTopic", "10", "testSpan");
return 0;
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.spring.autoconfigure.webmvc;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
import jakarta.servlet.Filter;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;

/** Spring Boot auto configuration test for {@link WebMvcFilterAutoConfigurationSpring6}. */
class WebMvcFilterAutoConfigurationSpring6Test {
private final ApplicationContextRunner contextRunner =
new ApplicationContextRunner()
.withConfiguration(
AutoConfigurations.of(
OpenTelemetryAutoConfiguration.class,
WebMvcFilterAutoConfigurationSpring6.class));

@BeforeAll
static void setUp() {
assumeTrue(Boolean.getBoolean("testLatestDeps"));
}

@Test
@DisplayName("when web is ENABLED should initialize WebMvcTracingFilter bean")
void webEnabled() {
this.contextRunner
.withPropertyValues("otel.springboot.web.enabled=true")
.run(
context ->
assertThat(context.getBean("otelWebMvcInstrumentationFilter", Filter.class))
.isNotNull());
}

@Test
@DisplayName("when web is DISABLED should NOT initialize WebMvcTracingFilter bean")
void disabledProperty() {
this.contextRunner
.withPropertyValues("otel.springboot.web.enabled=false")
.run(
context ->
assertThat(context.containsBean("otelWebMvcInstrumentationFilter")).isFalse());
}

@Test
@DisplayName("when web property is MISSING should initialize WebMvcTracingFilter bean")
void noProperty() {
this.contextRunner.run(
context ->
assertThat(context.getBean("otelWebMvcInstrumentationFilter", Filter.class))
.isNotNull());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
package io.opentelemetry.instrumentation.spring.autoconfigure.webmvc;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assumptions.assumeFalse;

import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
import javax.servlet.Filter;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
Expand All @@ -22,6 +24,11 @@ class WebMvcFilterAutoConfigurationTest {
AutoConfigurations.of(
OpenTelemetryAutoConfiguration.class, WebMvcFilterAutoConfiguration.class));

@BeforeAll
static void setUp() {
assumeFalse(Boolean.getBoolean("testLatestDeps"));
}

@Test
@DisplayName("when web is ENABLED should initialize WebMvcTracingFilter bean")
void webEnabled() {
Expand Down

0 comments on commit 2cbfec8

Please sign in to comment.